This is a follow-up on a discussion about OpenMPI that started at http://www.open-mpi.org/community/lists/users/2015/06/27039.php and continued at https://github.com/open-mpi/ompi/pull/625
The attached test program does not produce correct results with gcc 4.9.2 and gcc 5.1.0 with -O1 or greater (gcc 4.8.7 is safe) At first glance, it seems gcc is not aware a wrapper can be added to posix_memalign and hence posix_memalign can have some side effects such as updating user global variables. A workaround is to declare the global variable as volatile. The expected output of this test program is : global = 0 changed ! global = 1 here are the full outputs with gcc 4.9.2 and 5.1.0 and from O0 to O3 $ gcc --version ; for i in 0 1 2 3 ; do echo ; echo opt = O$i ; gcc -o test.O$i -Wno-deprecated-declarations -O$i test.c ; ./test.O$i ; done gcc (GCC) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. opt = O0 global = 0 changed ! global = 1 opt = O1 global = 0 global = 1 opt = O2 global = 0 global = 0 opt = O3 global = 0 global = 0 $ gcc --version ; for i in 0 1 2 3 ; do echo ; echo opt = O$i ; gcc -o test.O$i -Wno-deprecated-declarations -O$i test.c ; ./test.O$i ; done gcc (GCC) 5.1.0 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. opt = O0 global = 0 changed ! global = 1 opt = O1 global = 0 global = 0 opt = O2 global = 0 global = 0 opt = O3 global = 0 global = 0 please note the different behaviour with O1 between gcc 4.9.2 and gcc 5.1.0 Could you please comment on this issue ? - is this a bug ? - is this a "feature" ? (e.g. a known to be aggressive optimization that explicitly requires the global variable is declared as volatile) Thanks and regards, Gilles
#include <stdlib.h> #include <malloc.h> int global; void *hook (size_t alignment, size_t size, const void *caller); void *hook (size_t alignment, size_t size, const void *caller) { global = 1; } int main (int argc, char *argv) { void * c; global = 0; printf ("global = %d\n", global); __memalign_hook = hook; if (0 == global) { posix_memalign(&c, 0x1000, 1); if (0 != global) printf ("changed !\n"); printf ("global = %d\n", global); } return 0; }