Strict alias in C

Question about type puns: Why does this code break the strict alias rules:

int main() 
{
int a = 1;
short j;

printf("%i ", j = *((short*)&a));
return 0;
}

This is not:

int main()
{
int a = 1;
short j;
int *p;

p=&a;
printf("%i ", j = *((short *)p));
return 0;
}

Build via gcc -fstrict-aliasing.

Thank you!

They all violate the strict aliasing rule, I will quote my answer here (emphasize my progress ):

code violates the 07002 which makes it illegal to access an object through a pointer of a different type, although access through a char * is allowed. The compiler is allowed to assume that pointers of different types do not point to the same memory and optimize accordingly.

gcc在-Wstrict-aliasing = n here The document is a bit more detailed, which says:

This option is only active when -fstrict-aliasing is active. It warns about code that might break the strict aliasing rules that the compiler is using for optimization. Higher levels correspond to higher accuracy (fewer false positives). Higher levels also correspond to more effort, similar to the way -O works. -Wstrict-aliasing is equivalent to -Wstrict-aliasing=3.

And describe each level as follows:

  • Level 1: Most aggressive, quick, least accurate. Possibly useful when
    higher levels do not warn but -fstrict-aliasing still breaks the code,
    as it has very few false negatives. However, it has many false
    positives. Warns for all pointer conversions between possibly
    incompatible types, even if never dereferenced. Runs in the front end
    only.

  • Level 2: Aggressive, quick, not too precise. May still have many false
    positives (not as many as level 1 though), and few false negatives
    (but possibly more than level 1). Unlike level 1, it only warns when
    an address is taken. Warns about incomplete types. Runs in the front
    end only.

  • Level 3 (default for -Wstrict-aliasing): Should have very few false
    positives and few false negatives. Slightly slower than levels 1 or 2
    when optimization is enabled. Takes care of the common pun+dereference< br> pattern in the front end: *(int*)&som e_float. If optimization is
    enabled, it also runs in the back end, where it deals with multiple
    statement cases using flow-sensitive points-to information. Only warns
    when the converted pointer is dereferenced. Does not warn about
    incomplete types.

Therefore, it is not guaranteed to capture all instances, and different levels have different degrees of accuracy Sex.

Usually, the effect you are looking for can be accomplished using type penalties through union, which I introduced in the answer linked above and gcc explicitly supports.

< /div>

Regarding the type pun question: Why does this code break the strict alias rules:

int main()< br />{
int a = 1;
short j;

printf("%i ", j = *((short*)&a));< br /> return 0;
}

This is not:

int main()
{
int a = 1;
short j;
int *p;

p=&a;
printf("%i ", j = *((short* )p));
return 0;
}

Build via gcc -fstrict-aliasing.

Thank you!

They all violate the strict aliasing rule, I will quote my answer here (emphasis on my progress):

code violates the 07002 which makes it illegal to access an object through a pointer of a different type, although access through a char * is allowed. The compiler is allowed to assume that pointers of different types do not point to the same memory and optimize accordingly.

gcc is a bit more detailed in the document -Wstrict-aliasing = n here, which says:

p>

This option is only active when -fstrict-aliasing is active. It warns about code that might break the strict aliasing rules that the compiler is using for optimization. Higher levels correspond to higher accuracy (fewer false positives). Higher levels also correspond to more effort, similar to the way -O works. -Wstrict-aliasing is equivalent to -Wstrict-aliasing=3.

And describe each level as follows:

  • Level 1: Most aggressive, quick, least accura te. Possibly useful when
    higher levels do not warn but -fstrict-aliasing still breaks the code,
    as it has very few false negatives. However, it has many false
    positives. Warns for all pointer conversions between possibly
    incompatible types, even if never dereferenced. Runs in the front end
    only.

  • Level 2: Aggressive, quick, not too precise. May still have many false
    positives (not as many as level 1 though), and few false negatives
    (but possibly more than level 1). Unlike level 1, it only warns when
    an address is taken. Warns about incomplete types. Runs in the front
    end only.

  • Level 3 (default for -Wstrict-aliasing): Should have very few false
    positives and few false negatives. Slightly slower than levels 1 or 2
    when optimization is enabled. Takes care of the common pun+dereference
    pattern in the front end: *(int*)&some_float.
    If optimization is
    enabled, it also runs in the back end, where it deals with multiple
    statement cases using flow-sensitive points-to information. Only warns
    when the converted pointer is dereferenced. Does not warn about
    incomplete types.

Therefore, it is not guaranteed to capture all instances, and different levels have different degrees of accuracy.

Usually, the effect you are looking for can be used through The combined type penalty is done, which I introduced in the answer linked above and gcc explicitly supports.

Leave a Comment

Your email address will not be published.