Proprietary compiler extensions can be handy, but they commit you to always using that compiler. This rule raises an issue when GNU extensions are
used, such as:
- Ternary operator with omitted second operand
- Case ranges in switch statements
- Expression statements, i.e. code blocks producing value
- Index range in array initializers
- A array initializer without
=
- A structure member initializer with a colon
- Decimal floating points numbers
_Decimal32
, _Decimal64
, and _Decimal128
- Structures and union without named data members
- Empty initializers
= {}
in pre-C23 code, as the feature was standardized in C23
Noncompliant code example
struct S {
int f;
};
struct S s[] = {
[0] { // Noncompliant
f : 0 // Noncompliant
}
[1 ... 3] = { // CHECK :8 :11 S3715:use of GNU array range extension
.f = 2
}
};
int fun(int p) {
switch (p) {
case 0 ... 1: // Noncompliant
do_the_thing();
break;
case 2:
//...
}
p = ({ // Noncompliant
int a = 10, b = 20;
(a * b) + 10;
});
return p ?: 0; // Noncompliant
}
_Decimal32 d32; // Noncompliant
struct Empty {}; // Noncompliant in C
Compliant solution
struct S {
int f;
};
struct S s[] = {
[0] = {
.f = 0
},
[1] = {
.f = 2
}
[2] = {
.f = 2
},
[3] = {
.f = 2
}
};
int fun(int p) {
switch (p) {
case 0:
case 1:
do_the_thing();
break;
case 2:
//...
}
int a = 10, b = 20;
p = (a * b) + 10;
return p ? p: 0;
}