Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does removing const from a pointer-to-const obey strict aliasing in C, and refer to the same object?

Does the following code in C have defined behavior?

int main() {
    const int i = 0;
    return *(int*)(&i);
}

I ask because 6.5/7 lists "a qualified version of a type compatible with the effective type of the object" as a valid alias. But the effective type of the object is const int, and I don't think int is a qualified version of const int (although the reverse is true). Neither are int and const int compatible (6.7.3/10).

Furthermore, 6.3.2.3/2 says that you can convert pointer types by adding qualifiers, and that the resulting pointer is equal. 6.3.2.3/7 says that you can convert any two pointer types (so the cast (int*)(&i) itself is permitted). But doesn't say that the resulting pointer refers to the same object or even that it is equal. All it says is that it can be converted back to the original type (in this case const int*). That is, even if the alias is legal it's not clear to me that the standard guarantees that my pointer conversion does indeed result in a pointer that refers to i.

So, does the standard actually define the behavior of my code, and if so where is this defined?

I'm aware that the code works in practice. I have in mind a hypothetical (and bizarre) implementation on which it doesn't work. I could ask whether that implementation conforms to the standard (and if not, what part it violates), but I don't want to muddy the waters if there are other respects in which my imagined implementation fails to conform. I will describe the implementation if anyone thinks it will help them answer the question.

like image 838
Steve Jessop Avatar asked Jan 21 '13 11:01

Steve Jessop


People also ask

What is strict aliasing and why do we care?

This is done because they referred to the same memory location. Strict Aliasing: GCC compiler makes an assumption that pointers of different types will never point to the same memory location i.e., alias of each other. Strict aliasing rule helps the compiler to optimize the code.

What is Aliasing in programming languages?

An alias occurs when different variables point directly or indirectly to a single area of storage. Aliasing refers to assumptions made during optimization about which variables can point to or occupy the same storage area.

What is pointer Aliasing in C?

Pointer aliasing is a hidden kind of data dependency that can occur in C, C++, or any other language that uses pointers for array addresses in arithmetic operations. Array data identified by pointers in C can overlap, because the C language puts very few restrictions on pointers.

How do you get around strict aliasing?

The answer typically is to type pun, often the methods used violate strict aliasing rules. Sometimes we want to circumvent the type system and interpret an object as a different type. This is called type punning, to reinterpret a segment of memory as another type.


1 Answers

It is at least implied that it works, by §6.7.3 p5:

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.

Note that for volatile-qualified types it says refer to, but for const-qualified types it just says modify, which implies that a non-modifying access is OK ("the exception that proves the rule").

It looks to me like you may have identified a defect in the standard, though.

like image 54
caf Avatar answered Sep 26 '22 19:09

caf