Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does (*p=*p) & (*q=*q); in C trigger undefined behavior

Why does (*p=*p) & (*q=*q); in C trigger undefined behavior if p and q are equal.

int f2(int * p, int * q)
{
  (*p=*p) & (*q=*q);
  *p = 1;
  *q = 2;
  return *p + *q;
}

Source (Nice article by the way): http://blog.frama-c.com/index.php?post/2012/07/25/On-the-redundancy-of-C99-s-restrict

like image 500
nawfel bgh Avatar asked Jun 28 '15 13:06

nawfel bgh


People also ask

What is the difference between * P and * p?

p is the value of p while *p is the value stored in the memory location pointed by p . When you want to indirectly access the value of an integer i , you can have an integer pointer point to it ( int *p = &i ) and use that pointer to modify the value of i indirectly ( *p = 10 ).

What is the * in * P called in C?

In C programming language, *p represents the value stored in a pointer. ++ is increment operator used in prefix and postfix expressions. * is dereference operator.

What is difference between * p ++ and ++* p?

The expression *p++ is treated as *(p++) as the precedence of postfix ++ is higher than *. Therefore the output of second program is “arr[0] = 10, arr[1] = 20, *p = 20 “. The expression *++p has two operators of same precedence, so compiler looks for associativity. Associativity of operators is right to left.

What is difference between P * P and &P?

If p is a pointer (effectively a memory address), then *p is the data that it is pointing to. The & as an operator is the "address of" operator. If p is a bit of data, then &p is a pointer pointing to the data.


1 Answers

The ruling of the C11 Standard on the statement

(*p=*p) & (*q=*q);

is:

P1

§6.5p3

The grouping of operators and operands is indicated by the syntax. 85) Except as specified later, side effects and value computations of subexpressions are unsequenced.

Since §6.5.10 Bitwise AND operator fails to mention sequencing of its operands, it follows that (*p=*p) and (*q=*q) are unsequenced.

P2

§6.5p2

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings. 84)

Both assignments (*p=*p) and (*q=*q) are unsequenced w.r.t. each other by §6.5p3, and have a side-effect on the same object if p==q. Therefore, if p==q, then by §6.5p2 we have UB.

P3

§3.4.3

undefined behaviour

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements.

By this clause we know that the standard imposes no requirements on UB. This is commonly interpreted by compilers as a license to ignore the possibility that such behaviour occurs.

In particular, it allows the compiler to not handle the case p == q, which means that it may assume that p != q.

P1+P2+P3 -> C1

Because (*p=*p) and (*q=*q) may be assumed by the combined premises P1, P2 and P3 not to invoke UB, they may also be assumed to be loads and stores to different memory locations. This also means that the return value of f2 must be 3 and not 4. If p == q, the Standard imposes no requirements on what occurs.

like image 82
Iwillnotexist Idonotexist Avatar answered Sep 28 '22 07:09

Iwillnotexist Idonotexist