Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does &((struct name *)NULL -> b) cause undefined behaviour in C11?

Code sample:

struct name {     int a, b; };  int main() {     &(((struct name *)NULL)->b); } 

Does this cause undefined behaviour? We could debate whether it "dereferences null", however C11 doesn't define the term "dereference".

6.5.3.2/4 clearly says that using * on a null pointer causes undefined behaviour; however it doesn't say the same for -> and also it does not define a -> b as being (*a).b ; it has separate definitions for each operator.

The semantics of -> in 6.5.2.3/4 says:

A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.

However, NULL does not point to an object, so the second sentence seems underspecified.

Also relevant might be 6.5.3.2/1:

Constraints:

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

However I feel that the bolded text is defective and should read lvalue that potentially designates an object , as per 6.3.2.1/1 (definition of lvalue) -- C99 messed up the definition of lvalue, so C11 had to rewrite it and perhaps this section got missed.

6.3.2.1/1 does say:

An lvalue is an expression (with an object type other than void) that potentially designates an object; if an lvalue does not designate an object when it is evaluated, the behavior is undefined

however the & operator does evaluate its operand. (It doesn't access the stored value but that is different).

This long chain of reasoning seems to suggest that the code causes UB however it is fairly tenuous and it's not clear to me what the writers of the Standard intended. If in fact they intended anything, rather than leaving it up to us to debate :)

like image 257
M.M Avatar asked Nov 13 '14 10:11

M.M


People also ask

What you mean by does?

present tense third-person singular of do.

Does meaning and examples?

Does references the performance or achievements of another. An example of does is telling a friend that your husband is in marketing, "He does marketing." Plural form of doe. Third-person singular simple present indicative form of do.

How do you write do?

delivery order in British English ▶ USAGE The abbreviation for delivery order is D/O or d.o.

What do you mean by a symbol?

1 : something that stands for something else : emblem The eagle is a symbol of the United States. 2 : a letter, character, or sign used instead of a word to represent a quantity, position, relationship, direction, or something to be done The sign + is the symbol for addition. symbol.


1 Answers

From a lawyer point of view, the expression &(((struct name *)NULL)->b); should lead to UB, since you could not find a path in which there would be no UB. IMHO the root cause is that at a moment you apply the -> operator on an expression that does not point to an object.

From a compiler point of view, assuming the compiler programmer was not overcomplicated, it is clear that the expression returns the same value as offsetof(name, b) would, and I'm pretty sure that provided it is compiled without error any existing compiler will give that result.

As written, we could not blame a compiler that would note that in the inner part you use operator -> on an expression than cannot point to an object (since it is null) and issue a warning or an error.

My conclusion is that until there is a special paragraph saying that provided it is only to take its address it is legal do dereference a null pointer, this expression is not legal C.

like image 145
Serge Ballesta Avatar answered Sep 21 '22 18:09

Serge Ballesta