Home | Manual | Static Analysis | Playground

Cake - C23 and Beyond

Warnings

Warnings can be enabled with -w<number> (e.g. -w2) and disabled with -wd<number> (e.g. -wd2). -wall enables all of them.

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(void)
{
    enum E1 e = A;
    return e == B; //warning 4: comparing different enums (enum E1, enum E2)
}

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)

// -w11
int main(void) { //warning 11: not following correct brace style {
    return 0;
}

12 multi-line comment

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

13 Line slicing occurred

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

14 String was sliced (not emitted)

Reserved (W_STRING_SLICED). Not emitted by the current compiler.

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 (not emitted)

Reserved (W_UNINITIALZED). Not emitted by the current compiler.

18 Returning address of local variable (not emitted)

Reserved (W_RETURN_LOCAL_ADDR). Not emitted by the current compiler.

19 Missing address-of operator (not emitted)

Reserved (W_MUST_USE_ADDRESSOF). Not emitted by the current compiler.

20 Array indirection issue

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

21 (unused)

22 Using object without being owner (not emitted)

Reserved (W_FLOW_NOT_OWNER). Not emitted by the current compiler.

23 Using temporary owner incorrectly (flow) (not emitted)

Reserved (W_FLOW_USING_TEMPORARY_OWNER). Not emitted by the current compiler.

24 Move-assignment to non-owner (not emitted)

Reserved (W_FLOW_MOVE_ASSIGNMENT_OF_NON_OWNER). Not emitted by the current compiler.

25 Assigning non-owner to owner (flow) (not emitted)

Reserved (W_FLOW_NON_OWNER_TO_OWNER_ASSIGN). Not emitted by the current compiler. The parse-time check for this case is warning 78.

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 (not emitted)

Reserved (W_FLOW_NON_NULL). Not emitted by the current compiler.

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(void)
{
    int i = u'ab'; //warning 41: Unicode character literals may not contain multiple characters.
    (void)i;
}

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 (not emitted)

Reserved (W_NULLABLE_TO_NON_NULLABLE). Not emitted by the current compiler.

61 Cast to same type (not emitted)

Reserved (W_CAST_TO_SAME_TYPE). Not emitted by the current compiler.

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
}

64 Mixed string literal prefixes

Concatenating literals with different encoding prefixes. A literal without prefix can be concatenated with a prefixed one; the result takes the prefix.

int main(void)
{
    const char* s1 = "abc " u8"def"; //ok, result is u8
    const char* s2 = u8"abc" L"def"; //warning 64: concatenation of string literals with different encoding prefixes
    (void)s1;
    (void)s2;
}

65 Signed to unsigned (not implemented)

Reserved. The check is not emitted yet.

66 Information note (reserved)

Reserved for informational notes attached to another diagnostic. Not emitted yet.

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;
}

73 Unknown escape sequence

int main(void)
{
    char c = '\q'; //warning 73: unrecognized character escape sequence '\q'
    (void)c;
}

74 Constant not exactly representable

int main(void)
{
    float f = 0.1; //warning 74: constant expression is not exactly representable in type 'float'
    (void)f;
}

Also checked in assignments, including bit-fields.

struct S { int b : 1; };
void f(void)
{
    struct S s;
    s.b = 1; //warning 74: constant expression 1 is not exactly representable in 'int : 1'
    (void)s;
}

For const objects initialized with constants, the same checks done for constexpr (error 1950) are reported as this warning, including conversions between integer and floating types.

int main(void)
{
    const int i = 1.5;       //warning 74: constant expression 1.5 is not exactly representable in 'const int'
    const float f = 16777217; //warning 74: constant expression 16777217 is not exactly representable in 'const float'
    (void)i;
    (void)f;
}

75 Pointer to integer conversion

int main(void)
{
    int i;
    int* p = &i;
    int n = p; //warning 75: pointer to integer conversion
    (void)n;
}

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
    {
    }
}

77 Static function declared but not defined

static void f(void); //warning 77: static function 'f' declared but not defined

int main(void)
{
    f();
}

78 Assigning non-owner to owner

#pragma check_annotations enable
void free(void* _Owner _Opt p);

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

79 Temporary owner assigned to non-owner

#pragma check_annotations enable
void* _Owner _Opt malloc(unsigned long size);

int main(void)
{
    void* _Opt p = malloc(1); //warning 79: cannot assign a temporary owner to non-owner object
    (void)p;
}

80 Pointer to owner expected

#pragma check_annotations enable

void take(int* _Owner _Opt* pp);

int main(void)
{
    int* _Opt p = 0;
    take(&p); //warning 80: pointer to owner expected at argument
}

81 Owner aliased through a non-owner pointer

#pragma check_annotations enable
void free(void* _Owner _Opt p);
void* _Owner _Opt malloc(unsigned long size);

int main(void)
{
    void* _Owner _Opt p = malloc(1);
    void* _Opt* q = &p; //warning 81: owner aliased through a non-owner pointer
    (void)q;
    free(p);
}

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
    {
    }
}

86 Format specifier mismatch

int printf(const char* fmt, ...);

int main(void)
{
    long n = 1;
    printf("%d", n); //warning 86: format for 'long' is '%ld', not '%d'
}

87 Implicit conversion to enum

enum color { RED, GREEN };

int main(void)
{
    enum color c = 1; //warning 87: implicit conversion from 'int' to 'enum color': did you mean 'GREEN'?
    (void)c;
}

88 Unannotated switch fall-through

int main(void)
{
    int i = 0;
    switch (i)
    {
    case 0:
        i++; //warning 88: unannotated fall-through between switch labels; add a 'break' or '[[fallthrough]];'
    case 1:
        break;
    }
}

89 malloc size is not a multiple of the pointee size

void* _Opt malloc(unsigned long size);

int main(void)
{
    int* _Opt p = malloc(10); //warning 89: argument to 'malloc' is not a multiple of the pointee size (4)
    (void)p;
}

90 Parameter points to uninitialized object at exit

Flow analysis. When the function returns, an object reachable from a pointer parameter is possibly uninitialized, for instance because it was destroyed. The caller still sees it through the pointer.

#pragma safety enable

struct Y { int i; struct Y* _Opt next; };
void y_destroy(_Dtor struct Y* p);

void f(struct Y* p)
{
    y_destroy(p);
} //warning 90: 'p' points to a possibly uninitialized object after the function returns (see line 8)

91 Assignment in condition

Extra parentheses silence it.

void f(int a, int b)
{
    if (a = b) //warning 91: assignment in condition, use '==' for comparison or extra parentheses to silence
    {
    }
    if ((a = b)) /* ok */
    {
    }
}

92 Type qualifier on return type

const or volatile on the returned value has no effect.

const int f(void); //warning 92: type qualifier 'const' on return type has no effect
const int* g(void); /* ok */

93 Find definition

Result of -find-definition (declaration or definition).

94 Unused macro

Macro not used in any of the files given to -unused-extern-report.

95 Unused external function

External function not used in any of the files given to -unused-extern-report.

96 Unused enumerator

Enumerator not used in any of the files given to -unused-extern-report.

97–126 Reserved / unused warnings

97 Flow analysis not done

Flow analysis has a limit on the number of objects (and values) tracked per function (FLOW_MAX_TRACKED_OBJECTS, 10000). When a function goes over it, the analysis of that function stops and this warning says which object contributed most, so the function can be split or simplified.

warning 97: flow analysis of this function was not done: 13671 objects tracked (limit 10000), 4530 of them are parts of an object of type 'struct parser_ctx'

The other diagnostics of the function are still reported; only the flow analysis is skipped.

126 va_start requires a C23 compiler

In C23 the second argument of va_start is optional (7.16.1.4). Cake converts va_start(ap) to va_start(ap, last) using the last named parameter. When the function has none (f(...)) or it is unnamed, the generated code keeps __builtin_c23_va_start(ap), which needs a C23 compiler.

#include <stdarg.h>

int f(...)
{
    va_list ap;
    va_start(ap); //warning 126: function has no named last parameter; the generated va_start requires a C23 compiler
    va_end(ap);
    return 0;
}

127 Unary minus on unsigned

int main(void)
{
    unsigned u = 1;
    unsigned v = -u; //warning 127: unary minus operator applied to unsigned type, result still unsigned
    (void)v;
}

Errors

630 Missing terminating '

631 Missing terminating "

632 Missing end of comment

633 Empty character constant

int main(void)
{
    char c = ''; //error 633: empty character constant
}

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

#define F(a) ## a //error 790: '##' cannot appear at the beginning of a replacement list

800 Expected struct type (not emitted)

Reserved (C_ERROR_EXPECTED_STRUCT_TYPE). Not emitted by the current compiler.

810 Expected type name (not emitted)

Reserved (C_ERROR_EXPECTED_TYPE_NAME). Not emitted by the current compiler.

820 Left operand is not arithmetic

struct s { int i; };
int main(void)
{
    struct s a = {0};
    return a * 2; //error 820: left is not an arithmetic type
}

830 Right operand is not arithmetic

struct s { int i; };
int main(void)
{
    struct s a = {0};
    return 2 * a; //error 830: right is not an arithmetic type
}

840 Left operand is not integer

int main(void)
{
    double d = 1.0;
    return d % 2; //error 840: left is not an integer type
}

850 Right operand is not integer

int main(void)
{
    double d = 1.0;
    return 2 % d; //error 850: right is not an integer type
}

860 Invalid type

enum E { A = 1.5 }; //error 860: enumerator initializer must be integer

870 Left operand is not scalar

struct s { int i; };
int main(void)
{
    struct s a = {0};
    return a && 1; //error 870: left operator is not scalar
}

880 Right operand is not scalar

struct s { int i; };
int main(void)
{
    struct s a = {0};
    return 1 && a; //error 880: right operator is not scalar
}

890 Incompatible pointer types

int main(void)
{
    int i = 0;
    double d = 0;
    int* p = &i;
    double* q = &d;
    return p == q; //error 890: incompatible pointer types
}

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 (not emitted)

Reserved (C_ERROR_LVALUE_ASSIGNMENT). Not emitted by the current compiler. Assignment to a non-lvalue is now reported as error 1230.

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

struct a { int i; };
struct b { int i; };
int main(void)
{
    struct a x = {0};
    struct b y = x; //error 950: incompatible types
}

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'

long long long i; //error 980: cannot combine with previous 'long long' declaration specifier

990 Expected declaration

int main(void)
{
    return 0;
}
} //error 990: expected declaration not '}'

1000 Static/type qualifiers not allowed here

int main(void)
{
    int a[static 3]; //error 1000: static or type qualifiers are not allowed in non-parameter array declarator
}

1010 Owner qualifier can only be used with pointers (not emitted)

Reserved (C_ERROR_OBJ_OWNER_CAN_BE_USED_ONLY_IN_POINTER). Not emitted by the current compiler.

1020 Redeclaration error


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

1030 Tag type mismatch with previous declaration

struct s { int i; };
union s u; //error 1030: use of 's' with tag type that does not match previous declaration.

1040 type specifier or qualifier expected

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

1050 Multiple enum definitions (not emitted)

Reserved (C_ERROR_MULTIPLE_DEFINITION_ENUM). Not emitted by the current compiler.

1060 static_assert failed

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

1070 override_state error (not emitted)

Reserved (C_ERROR_STATIC_SET). Not emitted by the current compiler.

1080 Static-state analysis failed (not emitted)

Reserved (C_FLOW_ANALIZER_ERROR_STATIC_STATE_FAILED). Not emitted by the current compiler.

1090 Unbalanced attribute

[[deprecated(]] void f(void); //error 1090: expected ']' before ')'

1100 Unexpected end of file (not emitted)

Reserved (C_ERROR_UNEXPECTED_END_OF_FILE). Not emitted by the current compiler. Unexpected end of file is now reported as error 970.

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

void f(int a[10]);
int main(void)
{
    int b[5];
    f(b); //error 1130: argument of size [5] is smaller than parameter of size [10]
}

1140 Token invalid in preprocessor expression

#if ()
#endif

1150 File not found (preprocessor)

#include <file>

1160 Missing parenthesis

#define F(a) a
int i = F((1); //error 1160: missing )

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

int main(void)
{
    int i = 0;
    switch (i)
    {
        _Defer { i++; } //error 1201: switch is jumping over or into defer
    case 0:
        break;
    }
}

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(void)
{
    1 = 2; //error 1230: lvalue required as left operand of assignment
}

1240 Character literal too large

int main()
{  
//TODO
}

1250 Pragma error (not emitted)

Reserved (C_ERROR_PRAGMA_ERROR). Not emitted by the current compiler.

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 (not emitted)

Reserved (C_ERROR_RETURN_LOCAL_OWNER_TO_NON_OWNER). Not emitted by the current compiler. This case is now reported as warning 78.

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(void)
{
    unsigned long long i = 99999999999999999999; //error 1350: integer literal is too large to be represented in any integer type
    (void)i;
}

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(void)
{
    int i = u8'ab'; //error 1370: Unicode character literals may not contain multiple characters.
    (void)i;
}

1380 Invalid token

int main(void)
{
    int i = 0x; //error 1380: invalid number
    (void)i;
}

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 (not emitted)

Reserved (C_ERROR_MACRO_REDEFINITION). Not emitted by the current compiler. Macro redefinition is now reported as warning 16.

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();
}

1880 Variably modified member

void f(int n)
{
    struct s { int a[n]; }; //error 1880: Variably modified types cannot be used as members of a structure or union.
}

1890 Variably modified type with static storage

void f(int n)
{
    static int a[n]; //error 1890: variably modified type with static storage
}

1900 typeof on a bit-field

struct s { int b : 3; };

int main(void)
{
    struct s x = {0};
    typeof(x.b) y; //error 1900: typeof used in bit-field
}

1910 Initialized variable-sized object

void f(int n)
{
    int a[n] = {1}; //error 1910: variable-sized object may not be initialized except with an empty initializer
}

1920 Include path too long

#include path exceeds the maximum path length.

1930 Write qualifier on a const pointee

#pragma safety enable
struct s { int i; };
void clear(_Clear const struct s* p) //error 1930: _Clear pointee cannot also be const
{
}

1940 Write qualifier must qualify the pointee

#pragma safety enable
struct s { int i; };
void clear(struct s _Clear p); //error 1940: _Clear must be used only at the pointed object

1950 constexpr value not representable

int main(void)
{
    constexpr unsigned char c = 300; //error 1950: constant expression is not exactly representable in type
}

C23 6.7.1: the value of a constexpr initializer must be exactly representable in the object type. This includes conversions between integer and floating types. For const objects the same check is warning 74.

int main(void)
{
    constexpr int i = 1.5;        //error 1950: constant expression 1.5 is not exactly representable in 'const int'
    constexpr float f = 0.1;      //error 1950: constant expression 0.10000000000000001 is not exactly representable in 'float'
    constexpr float g = 16777217; //error 1950: constant expression 16777217 is not exactly representable in 'const float'
}

1960 struct/union comparison

struct s { int i; };
int main(void)
{
    struct s a = {0}, b = {0};
    return a == b; //error 1960: struct/union comparison illegal
}

1970 Invalid use of void

int main(void)
{
    void v; //error 1970: this use of 'void' is not valid
}

1980 extern with initializer at block scope

int main(void)
{
    extern int i = 1; //error 1980: 'i': cannot initialize extern variables with block scope
}

1990 void parameter not alone

void f(void, int i); //error 1990: 'void' must be the first and only parameter if specified

2000 Operator cannot be applied

struct s { int i; };
int main(void)
{
    struct s a = {0};
    a = -a; //error 2000: operator cannot be applied to an operand of the given type
}

2010 typedef used for function definition

typedef int F(void);
F f { return 0; } //error 2010: typedef cannot be used for function definition

2020 Duplicate type qualifier

const const int i = 0; //error 2020: same type qualifier used more than once

2030 typedef missing tag name

typedef struct; //error 2030: 'typedef': missing tag name

2040 Redefinition as typedef

int x;
typedef int x; //error 2040: 'x': redefinition; symbol cannot be overloaded with a typedef

2050 Invalid declaration in a controlling clause

C2y: if and switch can have a declaration in the controlling clause. Only auto, constexpr and register storage-class specifiers are allowed, and the declaration must declare exactly one object.

int main(void)
{
    if (static int i = 1) { } //error 2050: storage-class specifiers other than 'auto', 'constexpr' or 'register' are not allowed in the controlling clause of 'if'
    if (int i = 1, j = 2) { } //error 2050: a declaration in the controlling clause of 'if' must declare exactly one object
}

2060 Invalid _BitInt width

C23 6.7.3.1: the width of _BitInt(N) must be a positive integer constant expression, at least 2 for signed _BitInt, and not greater than BITINT_MAXWIDTH. Cake supports widths up to 64.

signed _BitInt(1) a; //error 2060: signed _BitInt must have a width of at least 2
_BitInt(0) b;        //error 2060: _BitInt width must be greater than zero
_BitInt(128) c;      //error 2060: _BitInt width 128 exceeds the maximum supported width 64

2070 Tag redefinition with different content

C23 (N3037) allows a struct, union or enum tag to be defined more than once in the same scope as long as every definition has the same content. A definition that differs is an error.

struct X { int a; };
struct X { int a; };  // ok: same content
struct X { long a; }; //error 2070: redefinition of 'struct X' with different content

int main(void)
{
    return 0;
}

2080 Too many storage-class specifiers

C23 6.7.1p2: at most one storage-class specifier is allowed, except that thread_local may appear with static or extern, auto with any other except typedef, and constexpr with auto, register or static.

extern static int i;      //error 2080: at most one storage-class specifier is allowed, ...
extern constexpr int j = 1; //error 2080: at most one storage-class specifier is allowed, ...
static constexpr int k = 1; // OK

2090 _Atomic qualifier on array type

C11 6.7.3 does not allow _Atomic to qualify an array type.

_Atomic int a[5]; //error 2090: '_Atomic' qualifier cannot be applied to array types

2100 _Atomic qualifier on function type

C11 6.7.3 does not allow _Atomic to qualify a function type.

_Atomic void f(void) {} //error 2100: '_Atomic' qualifier cannot be applied to function types

2110 Alignment specifier on bit-field

C11 6.7.5p2 does not allow an alignment specifier on a bit-field declaration.

struct S {
    alignas(16) int x : 4; //error 2110: alignment specifier cannot be used in a bit-field declaration
};

2120 Alignment specifier on function declaration

C11 6.7.5p2 does not allow an alignment specifier on a function declaration.

alignas(16) void f() {} //error 2120: alignment specifier cannot be used in function declaration

2130 Alignment specifier less strict than natural alignment

C11 6.7.5p6 requires an explicit alignment to be at least as strict as the type's natural alignment.

alignas(4) double d; //error 2130: requested alignment 4 is less than minimum alignment 8

2140 Alignment specifier with register

C11 6.7.5p2 does not allow an alignment specifier on a declaration with the register storage class.

void f() {
    register alignas(16) int x = 0; //error 2140: alignment specifier cannot be used with 'register'
}

2150 Alignment specifier with typedef

C11 6.7.5p2 does not allow an alignment specifier on a typedef declaration.

typedef alignas(16) int aligned_int; //error 2150: alignment specifier cannot be used with 'typedef'

2160 Alignment specifier not an integer constant expression

C11 6.7.5p3 requires the alignas(expression) operand to be an integer constant expression.

alignas(8.0) int y; //error 2160: alignment specifier must be an integer constant expression

2170 auto storage-class specifier at file scope

C11 6.9p2 does not allow the auto storage-class specifier in a file-scope declaration (this is the traditional C89 meaning of auto, not the C23 type-inference form, which requires an initializer and no explicit type).

auto int x; //error 2170: 'auto' storage-class specifier cannot be used in a file-scope declaration

2180 register storage-class specifier at file scope

C11 6.9p2 does not allow the register storage-class specifier in a file-scope declaration.

register int x; //error 2180: 'register' storage-class specifier cannot be used in a file-scope declaration

2190 Array designator not an integer constant expression

C23 6.7.11p6 requires an array designator's constant expression to have integer type.

int a[3] = { [1.5] = 1 }; //error 2190: array designator must be an integer constant expression

2200 Enum tag without body or fixed underlying type

C23 6.7.3.3p3: an enum type-specifier naming a tag with neither an enumerator-list nor a fixed underlying type must refer to a previously completed enum with that tag.

enum MyEnum; //error 2200: enum declared without enumerator list must have a fixed underlying type or a previous complete declaration

2210 Duplicate enumeration constant in the same scope

C23 6.2.1p3 does not allow two enumerators in the same scope to share a name — whether they belong to the same enum or to two different ones.

enum Color {
    RED,
    RED //error 2210: duplicate enumeration constant 'RED' in the same scope
};

int main(void)
{
    enum X { A = 1 };
    enum Y { A = 2 }; //error 2210: duplicate enumeration constant 'A' in the same scope
    return 0;
}

2220 Bit-precise integer type as enum underlying type

C23 6.7.3.3p4 restricts an enum's fixed underlying type to char, a signed or unsigned integer type, or bool — a _BitInt(N) type is not allowed.

enum E : _BitInt(16) { //error 2220: a bit-precise integer type is not allowed as an enum underlying type
    A = 1
};

2230 restrict qualifier on a non-pointer type

C23 6.7.3.1p1 only allows the restrict qualifier on a pointer type.

int restrict x = 10; //error 2230: 'restrict' qualifier can only be applied to a pointer type

2240 Static object in an inline function with external linkage

C11 6.7.4p7 does not allow an inline function with external linkage to contain a definition of an object with static storage duration.

inline void f() {
    static int counter = 0; //error 2240: an inline function with external linkage shall not contain a static object
    counter++;
}

2250 Function specifier on a non-function declaration

C11 6.7.4p2 restricts inline and _Noreturn to declarations of functions.

inline int x = 5; //error 2250: a function specifier can only be used in the declaration of a function

2260 Cast to or from a non-scalar type

C11 6.5.4p2 requires both the cast's target type and its operand to have scalar type (or the target may be void).

struct Point { int x, y; };

int main() {
    struct Point p = {10, 20};
    (int)p; //error 2260: operand of cast expression must have scalar type
    return 0;
}

2270 Comparing nullptr_t with a non-pointer type

C23 6.5.10p2/6.5.9p2: nullptr_t only compares with nullptr_t, a pointer type, or a null pointer constant.

int main() {
    int x = 0;
    if (nullptr == x) { //error 2270: both operands to comparison must have type 'nullptr_t' or a pointer type
    }
    return 0;
}

2280 thread_local on a function

C23 6.7.1p3: thread_local shall not be used in the declaration of a function.

thread_local void f() { //error 2280: 'thread_local' cannot appear in a function declaration
}

2290 Invalid storage-class specifier in a parameter declaration

C11 6.7.6.3p2 allows only register as a storage-class specifier in a parameter declaration (the array-bound static form, e.g. int arr[static 5], is a separate feature and is not affected by this check).

void f(static int x) { //error 2290: the only storage-class specifier allowed in a parameter declaration is 'register'
}

2300 thread_local missing from a redeclaration

C23 6.7.1p4: all declarations of an object with thread storage duration shall include thread_local.

thread_local int z = 5;
int z; //error 2300: 'z': redeclaration is missing 'thread_local'

2310 Inconsistent alignment specifier in a redeclaration

C23 6.7.5p8: if multiple declarations of an object specify an alignment, they must all specify the same alignment.

alignas(16) int var;
int var; //error 2310: 'var': alignment specifier is not consistent with the previous declaration

2320 Function implicitly converted to an object pointer type

A function designator is not implicitly convertible to an object pointer type such as void * (only to a compatible function pointer type).

void f() {}

int main() {
    void *ptr = f; //error 2320: a function shall not be implicitly converted to an object pointer type
    return 0;
}

2330 Empty initializer for an array of unknown size

C23 6.7.11p4-ish: an array of unknown size takes its size from the number of elements in its initializer; an empty initializer provides none, which would make the array size zero.

int arr[] = {}; //error 2330: array of unknown size cannot be initialized with an empty initializer

2340 constexpr object with volatile or atomic type

C23 6.7.1p5: a constexpr object shall not be volatile-qualified or have atomic type.

constexpr volatile int b = 20; //error 2340: a constexpr object cannot be volatile-qualified or have volatile-qualified members

Members are also checked, at any level.

struct S { volatile int v; };
constexpr struct S s = { 1 }; //error 2340: a constexpr object cannot be volatile-qualified or have volatile-qualified members

2350 Declaration that declares nothing

A declaration (or member declaration) with no declarator must at least introduce a struct, union, or enum tag — otherwise it declares nothing.

int; //error 2350: declaration does not declare anything

2360 Flexible array member in a union

C11 6.7.2.1p3: a flexible array member (an incomplete array as the last member) is only allowed in a struct, not a union.

union U {
    int size;
    int array[]; //error 2360: a flexible array member is not allowed in a union
};

2370 Array designator in a struct or union initializer

C23 6.7.10p7: an array designator [n] is only allowed when the current object is an array. For a struct or union use a member designator .name.

struct P { int x, y; };
struct P p = { [0] = 1 }; //error 2370: array designator in a struct or union initializer

2380 constexpr pointer not null

C23 6.7.1: the only value a constexpr pointer can have is a null pointer. const pointers are not affected.

int g;
constexpr int* p = &g;      //error 2380: a constexpr pointer must be initialized with a null pointer constant
constexpr int* q = nullptr; // OK
const int* r = &g;          // OK