With -Wsequence-point
enabled, GCC should warn user when undefined behavior code is spotted. For example
b = a + ++a;
should be noticed by GCC and should be reported as "undefined behavior" code (because ISO C doesn't specify the order of evaluating operands for addition).
However, I played with the syntax and I tried this one:
int *a = malloc(sizeof(int) * 2);
a[0] = 1;
printf("%d\n", *(a + (*a)++ - *a));
Of course, I got the warning
warning: operation on '*a' may be undefined [-Wsequence-point]
which is what I expected, because the value of *a
(which is a[0]
) may be incremented or may not be while processing the third operand. But, I tried the following one:
int *a = malloc(sizeof(int) * 2);
a[0] = 1;
printf("%d\n", *(a + (*a)++ - 1));
I was surprised because I got no warnings. Shouldn't this be UB too? I mean, according to ISO C99, post increment operation may be evaluated at any point durring expression evaluation (except for comma operators and ternary operators). In my latter example, I am not incrementing pointer, but instead the integer it points to. So, accordning to the standard, it can be incremented at any point (which means that it can be incremented after whole expression is evaluated), so the program may print both 1
or 2
, right?
Why doesn't GCC throw any warnings? Or did I miss something? Did I wrongly understand the specs?
To enable all warnings, use following list of warnings (probably some warnings are duplicated, because I didn't bother to filter warnings enabled by -Wall ). Show activity on this post. Someone has created a set of tools for determining the complete set of warnings for a given GCC or Clang version.
You can use the -Werror compiler flag to turn all or some warnings into errors. Show activity on this post. You can use -fdiagnostics-show-option to see the -W option that applies to a particular warning.
If -Wfatal-errors is also specified, then -Wfatal-errors takes precedence over this option. Inhibit all warning messages. Make all warnings into errors.
gcc -Wall enables all compiler's warning messages. This option should always be used, in order to generate better code.
Static analysis tool of gcc does not handle this situation.
The expression *(a + (*a)++ - x)
is too hard for static analysis of gcc, because it results in undefined behavior due to lack of sequence point under some very specific circumstances - namely, when *a
contains x
. This is when (*a)++ - x
"undo" each other, so overall expression becomes equivalent to *a
plus some side effects.
In order for gcc code analysis to spot this error, the compiler must track the content of *a
throughout its lifetime. Although it looks simple in your example, a more complex program, say, where data is read into a
from user input, renders such analysis impossible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With