Home | Manual | Static Analysis | Playground

Cake - C23 and Beyond

Warnings

Warnings can be enabled with -w0123 where 123 is the warning number, or disabled with -wd0123.

All warning are configurable. Cake has errors, warnings and notes. We can make a warning to be a note or error using pragma.

#pragma CAKE diagnostic push
#pragma CAKE diagnostic error 4
    

    /*
      4 is not reported as error
      code..
    
    */

#pragma CAKE diagnostic pop

1 #warning directive (preprocessor)

#warning message

2 Unused variable

// -w02
void f()
{
    int i;    
}

3 Deprecated

[[deprecated]] void f2() {}

int main(void)
{
    f2();
}

4 Enum conversion issue

enum E1 {A};
enum E2 {B};
int main()
{    
   enum E1 = B;
}

5 token sliced

6 Unused function parameter (disabled by default)

// -w06
void f(int i) {}

7 Declarator hides previous declaration

void f() {
    int i;
    {
      int i;
    }
}

8 typeof used on array parameter

void f(int a[])
{
    typeof(a) p;
}

9 ignoring the result of _Owner type

#pragma safety enable
int *_Owner f();
int main()
{
  f();  //warning C0009: ignoring the result of _Owner type 
}

10 Expression result not used

int main()
{  
  int a = 0;
  a++;
  
  a; //warning C0010: expression result not used
  1; //warning C0010: expression result not used
 
}

11 Style issue (disabled by default)

//-w011
int main() { //  warning C0011: not following correct brace style
}

12 multi-line comment

int main()
{  
  // \
  a++; 
}

13 Line slicing occurred

int a \
   = 1; // warning C0013: unnecessary line-slicing
}

14 String was sliced

int main()
{  
//TODO
}

15 Discarded qualifiers

char* f(){
    static const char s[] = "a";
    return s; //warning C0015:  discarding const
}

Both operands of ?: contribute: per C11 6.5.15p6 the result of a pointer conditional is qualified with the qualifiers of both referenced types, so a const operand makes the whole result const.

Not reported: an explicit cast that removes the qualifier (g((struct X*)p)). That is legal C -- the cast is the author taking responsibility -- so no diagnostic is possible, and none of the const checks can see through it.

struct X { int i; };
struct X* g_ptr;

void f(const struct X* p, int c)
{
    struct X* q = c ? p : g_ptr; //warning C0015: discarding const qualifier
    (void)q;
}

16 (unused)

17 Uninitialized variable

int main()
{  
 int i;
 int j = i;
}

18 Returning address of local variable (TODO)

int * f()
{  
    int i;
    return &i;
}

19 Missing address-of operator

int main()
{  
//TODO
}

20 Array indirection issue

void f(int a[])
{
    *a =1; // warning C0020: array indirection
}

21 (unused)

22 Using object without being owner

int main()
{  
//TODO
}

23 Using temporary owner incorrectly (flow)

int main()
{  
//TODO
}

24 Move-assignment to non-owner

int main()
{  
//TODO
}

25 Assigning non-owner to owner (flow)

#pragma safety enable

void  f(int * _Owner);
int main()
{
  int * _Opt p = 0;
  f(p); // warning C0025: cannot assign a non-owner to owner
}

26 Discarding an owner (flow)


#pragma safety enable

void* _Owner _Opt malloc(unsigned long size);

void f(int * _Opt p){}

int main() {
   f((int*)malloc(1)); //warning C0026: discarding _Owner pointer   
}

27 (unused)

28 Non-null flow violation

#pragma nullable enable

void f(int *p)
{
  if (p) //warning C0028: pointer is always not-null
  {   
  }
}
int main() {}
#pragma nullable enable

int main() {
  int * _Opt p = 0;
  if (p) //warning C0028: pointer is always null
  {   
  }
}

See object lifetime

29 pointed object was not released (flow)

#pragma safety enable

struct X {
    char* _Owner text; 
};

void delete_x(struct X *_Owner p) //warning C0029: object pointed by 'p' was not released.
{
}
int main() {}

30 Uninitialized value (flow)

This warning is issued when a local variable is used before it has been initialized.

#pragma safety enable

void f(int i)
{
    int j;
    if (i) j =1;
    i = j; //warning C0030: object 'j' can be uninitialized
}
int main() {}


#pragma safety enable

void* _Owner _Opt malloc(unsigned long size);
void free(void* _Owner _Opt ptr);

struct X{
    char* _Owner _Opt p;
};
struct X makeX();
void destroyX([[dtor]]struct X * p){
  free(p->p);
}

int main() {
    struct X x = makeX();
    destroyX(&x);
    destroyX(&x); //double free
}

31 Lifetime has ended (flow)


#pragma safety enable

struct X { int i; };

int main() {
    struct X * _Opt p = 0;
    {
      struct X x ={};
      p = &x;
    }
    p->i = 0; //warning C0031: operator -> applied to 'p->i': pointed object lifetime has ended (see line ...)
}

See object lifetime

32 Object already moved (flow)


#pragma safety enable

void* _Owner _Opt malloc(unsigned long size);
void free(void* _Owner _Opt ptr);

int main() {
   void * _Owner _Opt p = malloc(1);
   void * _Owner _Opt p2 = p;
   void * _Owner _Opt p3 = p; //warning C0032: object may be already moved
   free(p2);
}

33 Null dereference (flow)

This warning indicates that your code dereferences a potentially null pointer.

#pragma safety enable
int main()
{
  int * _Opt p = 0;
  *p =1; //warning C0033: possible null pointer dereference '*p'
}

34 (not used flow)

35 Nullable converted to non-nullable (flow)

#pragma safety enable

void f(int *p);
int main()
{
  int * _Opt p = 0;
  f(p); // warning C0035: passing a possible null pointer 'p' to non-nullable pointer parameter
}

36 Division by zero (flow)

#pragma safety enable

void f(int i)
{
    if (i > 0)
     i = 0;
    else
     i =1;

    int j = 1/i; //warning C0036: possible division by zero
}

37 Division by zero (without flow analysis)

int main()
{
    const int i = 0;
    int j = 1/i; //warning C0037: division by zero
}

38 (not used)

39 Passing null as array

void f(int a[]){}
int main(){
    f(0); //warning C0039:  passing null as array
}

40 Incompatible enum types

enum E1 {A};
enum E2 {B};
int main()
{    
   enum E1 e = B; //warning C0040:  incompatible types
}

41 Multi-character literal

int main()
{  
  int i = 'abc';
}

42 Out-of-bounds access

int main()
{  
  int a[2]= {0};
  a[2] = 1; //warning C0042: index 2 is past the end of the array
}

43 Assignment to array parameter

void f(int a[]){
    a = 1; // warning C0043: assignment to array parameter
}

44 Conditional is constant (currently disabled)

int main()
{  
  if (1) {
  }
}

45 Suspicious switch statement

int main()
{
    bool b =1;
    switch(b){ //warning C0045: switch condition has boolean value
        case 1:break;
    }
}

46 Unusual null pointer constant

int main()
{
    int * p = '\0'; //warning C0046: unusual expression/type used as null pointer constant
}

47 sizeof applied to array argument

void f(int a[])
{
    sizeof(a); //warning C0047: sizeof applied to array function parameter
}

48 const object not initialized

int main()
{  
  const int i;
}

49 implicit conversion of nullptr constant to 'bool'

void f(bool b){}
int main(){
    f(nullptr); //warning C0049: implicit conversion of nullptr constant to 'bool'
}

50 Implicitly unsigned literal


int main(){
  long long a = 9223372036854775807;
  unsigned long long b = 9223372036854775808; // warning C0050: integer literal is too large to be represented in a signed integer type, interpreting as unsigned
  unsigned long long c = 9223372036854775808ULL;
}

51 Integer overflow


int main(){
  long long a = 9223372036854775807 + 2; //warning C0051: integer overflow
}

52 Invalid array size

int main()
{
    char a[2] = "1234"; // warning C0052: initializer for array is too long
}

53 (unused)

54 Incompatible types

void f(double * p);
int main()
{  
    int a;
    f(&a); // warning C0054:  incompatible types
}

55 Unused label

int main()
{  
  A: //warning C0055: label 'A' defined but not used
}

56 Redefining builtin macro

#define __FILE__ 1 //warning C0056: redefining built-in macro

57 Unused function

static void f(){};
int main()
{  
}

58 Boolean comparison issue

int main()
{
    bool b = false;
    int i = 2;
    if (b == i) //warning C0058: comparison bool with non bool
    {
    }
}

59 Expected warning did not occur

int main()
{
    bool b = false;
    bool i = false;
    if (b == i) //lint 58 warning C0059: warning 'C0058' was not recognized
    {
    }
}

60 Null pointer constant to non-nullable pointer

#pragma safety enable

int main() {  
  int * p2 = nullptr; //warning C0060: cannot convert a null pointer constant to non-nullable pointer
}

61 Cast to same type (inactive)

int main()
{  
  int i = (int) 0;
}

62 Too many initializers

int main()
{  
  int a[2] = {1, 2, 3};
}

63 Float out of range

int main() {
  float f = 1e300f; //warning C0063: floating constant exceeds range of float
}

63 Signed to unsigned

void f(unsigned i) { (void)i; }

int main(void) {
    int x = -5;
    f(-1);
    f(x);
    unsigned u = -2;
    return 0;
}

64–66 Reserved / unused warnings

67 compile_assert could not be proven (flow)

#pragma safety enable

int f();

int main() {
    int i = f();
    compile_assert(i == 1); //warning C0067: compile_assert failed: value could be any value, including zero, set at line 5 in "root"
}

68 Unreachable code (flow)

#pragma safety enable

int f() {
    return 1;
    return 2; //warning C0068: unreachable code
}

69 _Clear parameter pointee not zeroed at exit (flow)

#pragma safety enable

struct outer { int a; int c; };

void clear_outer_forgets_a_member(_Clear struct outer* p)
{
    p->a = 0;
    /* forgot p->c = 0; */
} //warning C0069: _Clear parameter 'p->c' is not zero at exit (see line 3)

70 Array index out of bounds (flow)

#pragma safety enable

int main(int cond) {
    int a[2];
    int i;
    if (cond) i = 2; else i = 3;
    a[i] = 1; //warning C0070: array index is past the end of the array (size 2)
}

71 _Out parameter pointee not initialized at exit (flow)

#pragma safety enable

struct outer { int a; int c; };

void ctor_outer_forgets_a_member(_Out struct outer* p)
{
    p->a = 1;
    /* forgot p->c = ...; */
} //warning C0071: _Out parameter 'p->c' is possibly not initialized at exit (see line 3)

72 Borrowed parameter's owner consumed at exit (flow)

#pragma safety enable

typedef unsigned long size_t;
char* _Owner _Opt strdup(const char* s);
void free(void* _Owner _Opt p);

struct person { char* _Opt _Owner name; };

void set(struct person* p, char* name)
{
    free(p->name);
    char* _Opt _Owner temp = strdup(name);
    if (temp == 0) return; //warning C0072: parameter 'p->name' was moved/released here (see line ...) but never reassigned -- only a _Dtor parameter may leave the caller's object consumed
    p->name = temp;
}

76 Logical operation on address of string constant

int main()
{
    char* pc;
    pc = "Hello";
    if (pc == "Hello") //warning C0076: logical operation on address of string constant
    {
    }
}

82 Parameter could point to const

The pointed object is never written through, and no pointer into it escapes somewhere that could write it later, so the parameter can promise more. The suggestion applies to every pointer spelling -- const int* p, const int a[], const int (*a)[10]. Passing it on to a const-qualified parameter keeps the promise; passing it to a non-const one does not.

Assigning to the pointer (p = 0) does not count -- that is about T* const p, not about the pointee. Neither does writing through a pointer member (p->buf[0] = 'x'), which does not modify *p and stays legal under const struct X*. Writing an array member (p->arr[0] = 1) does count.

Not reported. The check answers "does anything write through this parameter", not "would const compile", so it stays quiet whenever it loses track of the pointer:

The one case that can still produce a wrong suggestion is a pointer stored somewhere the assignment checks never visit, such as inside a compound literal.

// -w082
struct X { int i; };

int get_i(struct X* p)
{
    return p->i;
}

83 Parameter set but not used (disabled by default)

The caller already supplied a value, so assigning to the parameter and never reading it back makes the assignment dead. x++ and x += 1 count as a set only when their result is discarded -- while (x--) reads it.

Not reported: the same cases as 84 below.

// -w083
int side(void);

void f(int x)
{
    x = side();
}

84 Variable set but not used (disabled by default)

Assigned at least once and never read. A variable that is only initialized and never read is reported as 2 Unused variable instead. Taking the address of the variable, or declaring it volatile, suppresses the warning.

Not reported. Only the declarator an lvalue names is treated as set, so writing through a part of it is a use of the whole:

// -w084
int side(void);

void f(void)
{
    int n = 0;
    n = side();
}

85 Condition is always true or false (flow) (disabled by default)

The if condition is already decided by what flow analysis knows at that point, on every path reaching it -- so one of the two branches can never run. A condition whose value differs between paths is not reported.

Off by default: plenty of deliberate code has a decided condition (a guard kept for clarity, a test on a build-time macro), and inside a while/do body the analysis reasons from the state after one iteration, so a condition on a variable that body itself assigns can read as decided when the first iteration says otherwise. Enable it with -w085 when auditing.

// -w085
#pragma safety enable

int main() {
    int i = 1;
    if (i) //warning C0085: condition is always true
    {
    }
}

73–75, 77–81, 86–127 Reserved / unused warnings

Errors

630 Missing terminating '

631 Missing terminating "

632 Missing end of comment

640 _View is the default qualifier

#pragma safety enable

int main() {  
  int * _View i; //error C0640: invalid qualifier for pointer
}

650 Unexpected compiler error

Some internal error.

660 Too many arguments

void f(void);
int main()
{  
  f(1);
}

670 Too few arguments

void f(int i);
int main()
{  
  f();
}

680 Not found

int main()
{  
   i = 1;
}

690 No match for generic selection

int main(){
    int i;
    _Generic(i, double: 0); // error C0690: no match for generic
}

700 Subscripted value is neither array nor pointer

int main(){
    int i;
    i[0]; //error C0700: subscripted value is neither array nor pointer
}

710 Called object is not function or function pointer

int main(){
    int i;
    i(); // error C0710: called object is not a function or function pointer
}

720 Struct member not found

struct X{int a;};

int main()
{
  struct X x;
  x.b = 1; //error C0720: member 'b' not found in 'struct X'
  return 0;
}

730 Structure or union required

int main() {  
  int a;
  a.a = 1; // error C0730: structure or union required
}

740 Struct is incomplete

struct X;
int main(){
    struct X x;
}

750 case label or default not within a switch statement

int main() {
 case 1:;
}

760 'break' statement not in loop or switch statement

int main() {
 break;
}

770 'continue' statement not in loop statement

int main() {
 continue;
}

780 Indirection requires pointer operand

int main() {
    int i;
    *i = 1; //error C0780: indirection requires pointer operand
}

790 Invalid token

int main()
{  
//TODO
}

800 Expected struct type

int main()
{  
//TODO
}

810 Expected type name

int main()
{  
//TODO
}

820 Left operand is not arithmetic

int main()
{  
//TODO
}

830 Right operand is not arithmetic

int main()
{  
//TODO
}

840 Left operand is not integer

int main()
{  
//TODO
}

850 Right operand is not integer

int main()
{  
//TODO
}

860 Invalid type

int main()
{  
//TODO
}

870 Left operand is not scalar

int main()
{  
//TODO
}

880 Right operand is not scalar

int main()
{  
//TODO
}

890 Incompatible pointer types

int main()
{  
//TODO
}

900 Assignment of function

int main()
{
    main = 0;    
}

910 Assignment to array expression

int main()
{  
    int a[2] = {0};
    a = 1; //error C0910: assignment to expression with array type
}

920 Assignment of read-only object

Reported for any attempt to modify a const-qualified lvalue: assignment, compound assignment, and ++/-- (C11 6.5.2.4p1 and 6.5.3.1p1 both require a modifiable lvalue). Reaching the object through a const pointer or a const aggregate counts -- per C11 6.7.3p9 a qualifier on an array type qualifies the element type, so p->arr[0] is const when p is.

int main()
{
    const int i = 1;
    i = 2; 
}

struct X { int arr[4]; };

void f(const struct X* p)
{
    p->arr[0] = 1; //error C0920: assignment of read-only object
}

void g(void)
{
    const int i = 1;
    i++;           //error C0920: increment of read-only object
}

930 lvalue required as left operand of assignment

int main()
{  
  1 = 2; //error C1230: lvalue required as left operand of assignment
}

940 Condition must have scalar type

int main(){
    struct X {int i;} x;
    x ? 1 : 0; //error C0940: condition must have scalar type
}

950 Incompatible types

int main()
{  
//TODO
}

960 Expected constant expression

void f(int i)
{
    switch (i)
    {
        case i: //error C0960: expected constant expression
        break;
    }
}

970 Unexpected token

int main)

980 Cannot combine with previous 'long long'

int main()
{  
//TODO
}

990 Expected declaration

int main()
{  
//TODO
}

1000 Static/type qualifiers not allowed here

int main()
{  
//TODO
}

1010 Owner qualifier can only be used with pointers

int main()
{  
//TODO
}

1020 Redeclaration error


#pragma safety enable
int a;
double a; //error C1020: conflicting types for 'a' (int)

1030 Tag type mismatch with previous declaration

int main()
{  
//TODO
}

1040 type specifier or qualifier expected

struct X7
{
    goto  a; //error C1040: type specifier or qualifier expected
};

1050 Multiple enum definitions

int main()
{  
//TODO
}

1060 static_assert failed

int main()
{  
  static_assert(1 == 2); // error C1060: static_assert failed
}

1070 override_state error

int main()
{  
//TODO
}

1080 Static-state analysis failed

#pragma safety enable

int f();

int main() {   
    int i = f();
    assert_state(i, "not-zero"); //error C1080: assert_state failed
} 

1090 Unbalanced attribute

int main()
{  
//TODO
}

1100 Unexpected end of file

int main()
{  //error C0970: unexpected end of file

1110 throw used outside try block

int main()
{  
 throw; //error C1110: throw statement not within try block
}

1120 void function returning a value

void f(){
    return 1; //error C1120: void function 'f' should not return a value
}

1121 Non-void function missing return value

int f(){
  return; //error C1121: non void function 'f' should return a value
}

1130 Argument size smaller than parameter size

int main()
{  
//TODO
}

1140 Token invalid in preprocessor expression

#if ()
#endif

1150 File not found (preprocessor)

#include <file>

1160 Missing parenthesis

int main()
{  
//TODO
}

1170 Expression error

#if 1+
#endif

1180 Preprocessor error directive

#error message

1190 Too few arguments to macro

#define F(a, b) a
int main()
{
    F(1);  //error C1190: too few arguments provided to function-like macro invocation
}

1191 Too many arguments to macro

#define F(a, b) a
int main()
{
    F(1, 2, 3);  //error C1191: too many arguments provided to function-like macro invocation
}

1200 jump out of defer


int main()
{    
    _Defer 
    {
        goto target;  // constraint violation
    }

target:
    return 1;
}

1201 jump over defer

void f(int n)
{
    goto  target;
    _Defer {};    
    target:
}

1202 jump over VLA

void f(int n)
{
    goto  target;
    int a[n];    
    target:
}

1210 Missing macro argument

int main()
{  
//TODO
}

1220 Address of register variable

int main()
{  
    register int a;
    &a; //error C1220: address of register variable 'x' requested
}

1230 Operator requires lvalue

int main()
{  
 1 == 2;
}

1240 Character literal too large

int main()
{  
//TODO
}

1250 Pragma error

int main()
{  
//TODO
}

1260 Out of memory

Internal compiler error

1270 Invalid storage size

int a[-2]; // error C1270: sizeof 'a' is too large
int main() {
  int a[2147483647]; //error C1270: sizeof 'a' is too large
}

1280 Returning owner to non-owner

#pragma safety enable

int * g();

int * _Owner f(){
  return g(); //warning C0025: cannot assign a non-owner to owner
}

1290 auto requires a single declarator

int main()
{
   auto  * p = 0; //error C1290: 'auto' requires a plain identifier
}

1300 Multiple incompatible specifiers

long short s;

1310 Increment operator cannot be used on owner

#pragma safety enable
int main(){

    int * _Owner _Opt p = 0;
    p++; //error C1310: operator ++ cannot be used in _Owner pointers
}

1320 Decrement operator cannot be used on owner

#pragma safety enable
int main(){

    int * _Owner _Opt p = 0;
    p--; //error C1320: operator -- cannot be used in owner pointers
}

1330 Preprocessor division by zero

#if 1/0
#endif

1340 non-pointer to pointer error


void f(int * p);

int main() {
    int i;
    f(i); //error C1340: non-pointer to pointer   
}

1350 Literal overflow

int main()
{  
//TODO
}

1360 Character not encodable in one code unit

int main()
{
   unsigned char c = u8'ç';// error C1360: character not encodable in a single code unit.
}

1370 Multi-character literal error

int main()
{  
//TODO
}

1380 Invalid token

int main()
{  
//TODO
}

1390 Invalid argument to _Countof

int main(){
  int a;
  _Countof(a); //error C1390: argument of _Countof must be an array
}

1400 return used inside defer

int main(){  
  defer return 0; //error C1400: return cannot be used inside defer statement
}

1410 Function returns function type

int f()(int){} //error C1410: function returning function

1420 Function returns array type

int f()[2]{} //error C1420: function returning array

1430 Label not defined

int main(){
    goto A; //error C1430: label 'A' used but not defined
}

1440 Duplicate label

int main(){
    A:
    A: // error C1440: duplicated label 'A'
}

1450 Duplicate case label

void f(int i)
{
    switch(i)
    {
        case 1:
        break;
        case 1: //error C1450: duplicate case '1'
        break;
    }
}

1560 Array subscript is not an integer

int main(){
    int a[2];
    a[1.0] = 1; //error C1560: array subscript is not an integer
}

1570 Duplicate default generic association

int main()
{  
//TODO
}

1780 Multiple default labels in switch

void f(int i)
{
    switch(i)
    {
        default:
        break;
        default: //error C1780: multiple default labels in one switch
        break;
    }
}

1790 Pointer to floating type

int main()
{
    int *p = 0;
    double d = (double) p; //error C1790: pointer type cannot be converted to any floating type
}

1800 Floating type converted to pointer

int main()
{
    int *p = (int*)1.2; //error C1800: A floating type cannot be converted to any pointer type
}

1810 nullptr cast error

int main()
{
    int i = (int)nullptr; // error C1810: cannot cast nullptr_t to this type
}

1820 Macro redefinition

#define A 1
#define A 2 //error C1820: macro redefinition

1830 Invalid preprocessing directive

#blablabla //error C1830: invalid preprocessor directive '#blablabla'

1840 Function cannot be a member

struct X
{
    void f(); //error C1840: members having a function type are not allowed
};

1850 Non-integral enum type

enum E : double {A}; //error C1850: expected an integer type

1860 Requires compile-time constant

int a;
int b = a; //error C1860: requires a compile time object
int main()
{    
}

1870 Outer scope error


int main()
{
    int i;
    int dup() { return i * 2; } //error C1870: 'i' cannot be evaluated in this scope
    return dup();
}