Home | Manual | Static Analysis | Playground
Cake - C23 and Beyond
-
Warnings
- 1 #warning directive (preprocessor)
- 2 Unused variable
- 3 Deprecated
- 4 Enum conversion issue
- 5 token sliced
- 6 Unused function parameter (disabled by default)
- 7 Declarator hides previous declaration
- 8 typeof used on array parameter
- 9 ignoring the result of _Owner type
- 10 Expression result not used
- 11 Style issue (disabled by default)
- 12 multi-line comment
- 13 Line slicing occurred
- 14 String was sliced (not emitted)
- 15 Discarded qualifiers
- 16 (unused)
- 17 Uninitialized variable (not emitted)
- 18 Returning address of local variable (not emitted)
- 19 Missing address-of operator (not emitted)
- 20 Array indirection issue
- 21 (unused)
- 22 Using object without being owner (not emitted)
- 23 Using temporary owner incorrectly (flow) (not emitted)
- 24 Move-assignment to non-owner (not emitted)
- 25 Assigning non-owner to owner (flow) (not emitted)
- 26 Discarding an owner (flow)
- 27 (unused)
- 28 Non-null flow violation (not emitted)
- 29 pointed object was not released (flow)
- 30 Uninitialized value (flow)
- 31 Lifetime has ended (flow)
- 32 Object already moved (flow)
- 33 Null dereference (flow)
- 34 (not used flow)
- 35 Nullable converted to non-nullable (flow)
- 36 Division by zero (flow)
- 37 Division by zero (without flow analysis)
- 38 (not used)
- 39 Passing null as array
- 40 Incompatible enum types
- 41 Multi-character literal
- 42 Out-of-bounds access
- 43 Assignment to array parameter
- 44 Conditional is constant (currently disabled)
- 45 Suspicious switch statement
- 46 Unusual null pointer constant
- 47 sizeof applied to array argument
- 48 const object not initialized
- 49 implicit conversion of nullptr constant to 'bool'
- 50 Implicitly unsigned literal
- 51 Integer overflow
- 52 Invalid array size
- 53 (unused)
- 54 Incompatible types
- 55 Unused label
- 56 Redefining builtin macro
- 57 Unused function
- 58 Boolean comparison issue
- 59 Expected warning did not occur
- 60 Null pointer constant to non-nullable pointer (not emitted)
- 61 Cast to same type (not emitted)
- 62 Too many initializers
- 63 Float out of range
- 64 Mixed string literal prefixes
- 65 Signed to unsigned (not implemented)
- 66 Information note (reserved)
- 67 compile_assert could not be proven (flow)
- 68 Unreachable code (flow)
- 69 _Clear parameter pointee not zeroed at exit (flow)
- 70 Array index out of bounds (flow)
- 71 _Out parameter pointee not initialized at exit (flow)
- 72 Borrowed parameter's owner consumed at exit (flow)
- 73 Unknown escape sequence
- 74 Constant not exactly representable
- 75 Pointer to integer conversion
- 76 Logical operation on address of string constant
- 77 Static function declared but not defined
- 78 Assigning non-owner to owner
- 79 Temporary owner assigned to non-owner
- 80 Pointer to owner expected
- 81 Owner aliased through a non-owner pointer
- 82 Parameter could point to const
- 83 Parameter set but not used (disabled by default)
- 84 Variable set but not used (disabled by default)
- 85 Condition is always true or false (flow) (disabled by default)
- 86 Format specifier mismatch
- 87 Implicit conversion to enum
- 88 Unannotated switch fall-through
- 89 malloc size is not a multiple of the pointee size
- 90 Parameter points to uninitialized object at exit
- 91 Assignment in condition
- 92 Type qualifier on return type
- 93 Find definition
- 94 Unused macro
- 95 Unused external function
- 96 Unused enumerator
- 97–126 Reserved / unused warnings
- 97 Flow analysis not done
- 126 va_start requires a C23 compiler
- 127 Unary minus on unsigned
-
Errors
- 630 Missing terminating '
- 631 Missing terminating "
- 632 Missing end of comment
- 633 Empty character constant
- 640 _View is the default qualifier
- 650 Unexpected compiler error
- 660 Too many arguments
- 670 Too few arguments
- 680 Not found
- 690 No match for generic selection
- 700 Subscripted value is neither array nor pointer
- 710 Called object is not function or function pointer
- 720 Struct member not found
- 730 Structure or union required
- 740 Struct is incomplete
- 750 case label or default not within a switch statement
- 760 'break' statement not in loop or switch statement
- 770 'continue' statement not in loop statement
- 780 Indirection requires pointer operand
- 790 Invalid token
- 800 Expected struct type (not emitted)
- 810 Expected type name (not emitted)
- 820 Left operand is not arithmetic
- 830 Right operand is not arithmetic
- 840 Left operand is not integer
- 850 Right operand is not integer
- 860 Invalid type
- 870 Left operand is not scalar
- 880 Right operand is not scalar
- 890 Incompatible pointer types
- 900 Assignment of function
- 910 Assignment to array expression
- 920 Assignment of read-only object
- 930 lvalue required as left operand of assignment (not emitted)
- 940 Condition must have scalar type
- 950 Incompatible types
- 960 Expected constant expression
- 970 Unexpected token
- 980 Cannot combine with previous 'long long'
- 990 Expected declaration
- 1000 Static/type qualifiers not allowed here
- 1010 Owner qualifier can only be used with pointers (not emitted)
- 1020 Redeclaration error
- 1030 Tag type mismatch with previous declaration
- 1040 type specifier or qualifier expected
- 1050 Multiple enum definitions (not emitted)
- 1060 static_assert failed
- 1070 override_state error (not emitted)
- 1080 Static-state analysis failed (not emitted)
- 1090 Unbalanced attribute
- 1100 Unexpected end of file (not emitted)
- 1110 throw used outside try block
- 1120 void function returning a value
- 1121 Non-void function missing return value
- 1130 Argument size smaller than parameter size
- 1140 Token invalid in preprocessor expression
- 1150 File not found (preprocessor)
- 1160 Missing parenthesis
- 1170 Expression error
- 1180 Preprocessor error directive
- 1190 Too few arguments to macro
- 1191 Too many arguments to macro
- 1200 jump out of defer
- 1201 jump over defer
- 1202 jump over VLA
- 1210 Missing macro argument
- 1220 Address of register variable
- 1230 Operator requires lvalue
- 1240 Character literal too large
- 1250 Pragma error (not emitted)
- 1260 Out of memory
- 1270 Invalid storage size
- 1280 Returning owner to non-owner (not emitted)
- 1290 auto requires a single declarator
- 1300 Multiple incompatible specifiers
- 1310 Increment operator cannot be used on owner
- 1320 Decrement operator cannot be used on owner
- 1330 Preprocessor division by zero
- 1340 non-pointer to pointer error
- 1350 Literal overflow
- 1360 Character not encodable in one code unit
- 1370 Multi-character literal error
- 1380 Invalid token
- 1390 Invalid argument to _Countof
- 1400 return used inside defer
- 1410 Function returns function type
- 1420 Function returns array type
- 1430 Label not defined
- 1440 Duplicate label
- 1450 Duplicate case label
- 1560 Array subscript is not an integer
- 1570 Duplicate default generic association
- 1780 Multiple default labels in switch
- 1790 Pointer to floating type
- 1800 Floating type converted to pointer
- 1810 nullptr cast error
- 1820 Macro redefinition (not emitted)
- 1830 Invalid preprocessing directive
- 1840 Function cannot be a member
- 1850 Non-integral enum type
- 1860 Requires compile-time constant
- 1870 Outer scope error
- 1880 Variably modified member
- 1890 Variably modified type with static storage
- 1900 typeof on a bit-field
- 1910 Initialized variable-sized object
- 1920 Include path too long
- 1930 Write qualifier on a const pointee
- 1940 Write qualifier must qualify the pointee
- 1950 constexpr value not representable
- 1960 struct/union comparison
- 1970 Invalid use of void
- 1980 extern with initializer at block scope
- 1990 void parameter not alone
- 2000 Operator cannot be applied
- 2010 typedef used for function definition
- 2020 Duplicate type qualifier
- 2030 typedef missing tag name
- 2040 Redefinition as typedef
- 2050 Invalid declaration in a controlling clause
- 2060 Invalid _BitInt width
- 2070 Tag redefinition with different content
- 2080 Too many storage-class specifiers
- 2090 _Atomic qualifier on array type
- 2100 _Atomic qualifier on function type
- 2110 Alignment specifier on bit-field
- 2120 Alignment specifier on function declaration
- 2130 Alignment specifier less strict than natural alignment
- 2140 Alignment specifier with register
- 2150 Alignment specifier with typedef
- 2160 Alignment specifier not an integer constant expression
- 2170 auto storage-class specifier at file scope
- 2180 register storage-class specifier at file scope
- 2190 Array designator not an integer constant expression
- 2200 Enum tag without body or fixed underlying type
- 2210 Duplicate enumeration constant in the same scope
- 2220 Bit-precise integer type as enum underlying type
- 2230 restrict qualifier on a non-pointer type
- 2240 Static object in an inline function with external linkage
- 2250 Function specifier on a non-function declaration
- 2260 Cast to or from a non-scalar type
- 2270 Comparing nullptr_t with a non-pointer type
- 2280 thread_local on a function
- 2290 Invalid storage-class specifier in a parameter declaration
- 2300 thread_local missing from a redeclaration
- 2310 Inconsistent alignment specifier in a redeclaration
- 2320 Function implicitly converted to an object pointer type
- 2330 Empty initializer for an array of unknown size
- 2340 constexpr object with volatile or atomic type
- 2350 Declaration that declares nothing
- 2360 Flexible array member in a union
- 2370 Array designator in a struct or union initializer
- 2380 constexpr pointer not null
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 pointer is copied to another variable (
struct X* q = p;) -- writes throughqare not attributed back top; - the pointer goes through an explicit cast (
g((struct X*)p)), or is passed to a...parameter, or to any destination whose pointee is notconst; - the parameter is
_Out,_Dtor,_Clearor_Owner, all of which write the pointee by contract; - the parameter is never dereferenced at all -- a bare
(void)pis 6 Unused function parameter's subject, not this one; - the only dereference is inside an unevaluated operand --
sizeof(*p),_Countof,_Alignof, or the unselected arm of a_Generic-- which names the pointee's type without touching the object.
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:
a[0] = 1is a use ofa, ands.f = 1a use ofs, so neither array nor struct is reported even when nothing ever reads it back;*p = 1is a use ofp(it reads the pointer), never a set of it;sizeof(n)counts as a read, so it suppresses the warning;&nanywhere suppresses it -- the address escaping means a read can happen out of sight;volatilesuppresses it: writing a volatile object is the point.
// -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