views:

888

answers:

4

'Strict aliasing' optimization needs special care from the source code, s.a. using a union instead of pointer casts. Is there a way to detect using preprocessor directives (#if/else) whether the compiler is trying to do such optimizations?

I would like to maintain the old and non-strict-aliasing-prepared code path for processors and compilers that don't care. It seems faster.

Edit: GCC predefined macros does not seem to have anything about aliasing. In other words, I'm most interested on gcc 4.x, but also in a general solution (which does not seem to exist).

+2  A: 

Completely implementation dependant - you need to check the docs for your specific compiler(s). And when asking questions like this, it's a good idea to mention which compiler(s) you are using.

A semi-portable way to do this is from your Makefile - define different targets for aliased & unaliased versions and define your own STRICT_ALIASING (or whatever) preprocessor symbol for the aliased version.

anon
+1  A: 

For GCC, see the "may_alias" attribute

janneb
+1  A: 

There is no general solution. The closest is #ifdef __cplusplus, as standard C++ allows the compiler to assume pointers to different types are not aliased (unless they're char*). This happens even in simple scenario's like:

void (int *foo, float *bar) {
  *foo++;
  *bar = 0; // Can safely be scheduled between the load and store of foo.
}

Therefore, "strict aliasing" is not really the optimalization; "tolerating undefined behavior" is a pessimization.

MSalters
This is wrong. Both C and C++ allow aliasing between variables of the same type, but neither C nor C++ allow aliasing of different types (i.e. the strict aliasing optimization in GCC).
janneb
.. except for char, of course
janneb
A: 

To the best of my knowledge, there are no preprocessor directives for detecting strict aliasing.

If you are using gcc's "-Wall" then the compiler will warn you about code that may break the strict aliasing rule.

-Wstrict-aliasing --- This option is only active when ‘-fstrict-aliasing’ is active. It warns about code which might break the strict aliasing rules that the compiler is using for optimization. The warning does not catch all cases, but does attempt to catch the more common pitfalls. It is included in ‘-Wall’. It is equivalent to ‘-Wstrict-aliasing=3’

If the code you are working on is critical then you can disable -fstring-aliasing in gcc. Or if you don't want to disable strict aliasing, I suggest looking at the asm output to make sure the compiler isn't doing dangerous optimizations that you don't want.


As an aside, akauppi said in the comments:

'restrict' enables strict aliasing optimizations for particular pointers.

The restrict keyword does not "enable ... optimizations" directly but rather it gives the compiler more information and that extra information indirectly helps the compiler determine if it can apply specific optimization techniques.

A good explanation of the restrict keyword from TI's DSP compiler documentation:

To help the compiler determine memory dependencies, you can qualify a pointer, reference, or array with the restrict keyword. The restrict keyword is a type qualifier that may be applied to pointers, references, and arrays. Its use represents a guarantee by the programmer that within the scope of the pointer declaration the object pointed to can be accessed only by that pointer. Any violation of this guarantee renders the program undefined. This practice helps the compiler optimize certain sections of code because aliasing information can be more easily determined.

Trevor Boyd Smith
Sorry, you're wrong. 'restrict' enables strict aliasing optimizations for particular pointers. I asked how to detect if that optimization is globally, automatically, applied to _all_ pointers. Sorry, -1.
akauppi