Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can this C code run correctly? [duplicate]

Tags:

The C code likes this:

 #include <stdio.h>  #include <unistd.h>   #define DIM(a) (sizeof(a)/sizeof(a[0]))   struct obj  {      int a[1];  };  int main()  {      struct obj *p = NULL;      printf("%d\n",DIM(p->a));      return 0;  } 

This object pointer p is NULL, so, i think this p->a is illegal. But i have tested this code in Ubuntu14.04, it can execute correctly. So, I want to know why...


Note: the original code had int a[0] above but I've changed that to int a[1] since everyone seems to be hung up on that rather than the actual question, which is:

Is the expression sizeof(p->a) valid when p is equal to NULL?

like image 245
Yang. fr Avatar asked Aug 19 '15 02:08

Yang. fr


People also ask

How do you avoid code duplication?

How to Apply the Guideline. To avoid the problem of duplicated bugs, never reuse code by copying and pasting existing code fragments. Instead, put it in a method if it is not already in one, so that you can call it the second time that you need it.

Why is code duplication a problem?

Code duplication makes software less maintainable and reduces our ability to iterate fast.

How do you avoid code duplication in C++?

The C++11 delegating constructors reduce the code duplication and make effective use of the member initializer lists.

Is duplicated code always bad?

Duplication is bad, but… It isn't a question of whether you'll remember: it's a question of when you'll forget.” Which makes perfect sense. It's time well spent when you try to make your code streamlined and readable. You'll end up with a cleaner, easier-to-maintain, and more extensible code base as a result.


1 Answers

Because sizeof is a compile time construction, it does not depend on evaluating the input. sizeof(p->a) gets evaluated based on the declared type of the member p::a solely, and becomes a constant in the executable. So the fact that p points to null makes no difference.

The runtime value of p plays absolutely no role in the expression sizeof(p->a).

In C and C++, sizeof is an operator and not a function. It can be applied to either a type-id or an expression. Except in the case that of an expression and the expression is a variable-length array (new in C99) (as pointed out by paxdiablo), the expression is an unevaluated operand and the result is the same as if you had taken sizeof against the type of that expression instead. (C.f. C11 references due to paxdiablo below, C++14 working draft 5.3.3.1)

like image 65
Chris Beck Avatar answered Oct 02 '22 12:10

Chris Beck