C Programming Basics
int get(int *p) {
int v = *p;
if (p == NULL)
return -1;
return v;
}When the function above is compiled with gcc with optimization enabled, the check if (p == NULL) may be removed. Which of the following is the reason?
- A*p is read first, and if p were NULL that would already be undefined behavior, so the compiler may assume p is not NULL
- BThe standard specifies that comparison with NULL is always false
- CUnder optimization, if statements that check function arguments are regarded as the caller's responsibility and may all be removed
Show answer and explanation
Answer: A. *p is read first, and if p were NULL that would already be undefined behavior, so the compiler may assume p is not NULL
If p is NULL, int v = *p;, which runs first, dereferences a null pointer and is undefined behavior at that point. Because the compiler may assume undefined behavior does not happen, it concludes that p is not NULL since *p was read, and removes the p == NULL check and the return -1. With gcc 13 for x86-64 and -O2, the function becomes code that just reads *p and returns it, while at -O0 the check remains. To make the check effective, test p before reading *p.
- A. Correct. The dereference comes before the check, so p is inferred not to be NULL.
- B. Comparison with NULL is true when p is NULL. In this function, the cause is the *p before the check.
- C. Checks of arguments are generally not removed. They are removed only when the result can be inferred to be fixed.