问题
Compiler generates code assuming that an int
can be aliased by an unsigned int
. The folowing code:
int f(int& a, unsigned int& b){
a=10;
b=12;
return a;
}
int f(int& a, double& b){
a=10;
b=12;
return a;
}
generates the folowing assembly, using Clang5 (similar code is produced by GCC or ICC):
f(int&, unsigned int&): # @f(int&, unsigned int&)
mov dword ptr [rdi], 10
mov dword ptr [rsi], 12
mov eax, dword ptr [rdi] #return value must be loaded since rdi might equal rsi
ret
f(int&, double&): # @f(int&, double&)
mov dword ptr [rdi], 10
movabs rax, 4622945017495814144
mov qword ptr [rsi], rax
mov eax, 10 #return value is a direct value.
ret
In the example above, in the first overload f
the return value (in eax
register) is either 10 or 12 if b
and a
refer to the same object. In the second overload, a
and b
cannot refer to the same object so the return value is always 10.
The strict aliasing rule is expressed by this paragraph of the C++ standard, [intro.object]/8:
[...] Two objects a and b with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they have distinct addresses.
So according to this rule, an int
cannot be aliased by an unsigned int
.
Questions:
Is there an exception to this rule in the C++ standard that would allow aliasing of
int
byunsigned int
?If not, why all compilers assume this possibility?
回答1:
Is there an exception to this rule in the C++ standard that would allow aliasing of int by unsigned int?
Yes, it's [basic.lval]/8:
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
- a type that is the signed or unsigned type corresponding to the dynamic type of the object,
- a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
来源:https://stackoverflow.com/questions/48060240/can-an-int-be-aliased-as-an-unsigned-int