Reputation: 33
The following code running compiler options -O3
vs -O0
results different output:
#include <stdlib.h>
#include <stdio.h>
int main(){
int *p = (int*)malloc(sizeof(int));
int *q = (int*)realloc(p, sizeof(int));
*p = 1;
*q = 2;
if (p == q)
printf("%d %d", *p, *q);
return 0;
}
I was very surprised with the outcome.
Compiling with clang 3.4, 3.5 (http://goo.gl/sDLvrq)
using compiler options -O0
— output: 2 2
using compiler options -O3
— output: 1 2
Is it a bug?
Interestingly if I modify the code slightly (http://goo.gl/QwrozF) it behaves as expected.
int *p = (int*)malloc(sizeof(int));
*p = 1;
Testing it on gcc seems to work fine.
Upvotes: 3
Views: 852
Reputation: 8205
Assuming both of the allocations are successful, q
points to an allocated region of memory and p
is an invalid pointer. The standard treats realloc
and free
as deallocation routines, and if successful, the address the pointer held can no longer be used. If the call to realloc
fails for some reason, the original memory is still valid (but of course q
isn't, it's NULL).
Although you compare p
and q
, you've already written to an invalid pointer, so all bets are off.
What's probably happening here is that the O3
setting is causing the compiler to ignore the pointers and just substitute numbers inline. High optimisation means a compiler can take all sorts of short cuts and ignore statements so long as it guarantees the same result - the condition being that all of the code is well defined.
Upvotes: 3