Reputation: 30058
I just read about Statement Expressions Extension in GCC, and I found some unexpected behavior when using it.
Please observe this example:
#include <stdio.h>
int main(void)
{
char* res1 = ({
char arr[] ={'h', 'e', '\0'}; // was char *arr[]
arr[0] = 'x';
char* ptr = arr;
ptr;
});
char* res2 = ({
char arr[] ={'h', 'e', '\0'}; // was char *arr[]
arr[0] = 'X';
char* ptr = arr;
ptr;
});
printf ("%s %p\n", res1, res1);
printf ("%s %p\n", res2, res2);
return 0;
}
Output:
X 0x7fff93098160
X 0x7fff93098160
I noticing that, the variables arr
in first block and arr
in second block taking the same memory address.
Why that happening??
Upvotes: 3
Views: 553
Reputation: 19721
As far as I understand, the scope of variables defined in statement expressions is just those statement expressions themselves. That is, when res1
is initialized, the array is already out of scope, and the pointer points to unallocated memory. The array in the second statement expression happens to occupy the same memory. It's actually not much different from the following code:
char* res1;
{
char arr[] ={'h', 'e', '\0'};
arr[0] = 'x';
char* ptr = arr;
res1 = ptr;
}
char* res2;
{
char arr[] ={'h', 'e', '\0'};
arr[0] = 'X';
char* ptr = arr;
res2 = ptr;
}
printf ("%s %p\n", res1, res1);
printf ("%s %p\n", res2, res2);
Upvotes: 3
Reputation: 263257
Both occurrences of arr
are array objects with automatic storage duration; they're local to the enclosing block { ... }
within the statement expression.
Each statement expression grabs the address of that local variable; that address is saved in res1
and res2and used *after* the end of the block, when the object
arr` no longer exists.
This is the same problem as a function returning the address of a local variable. The address becomes invalid when the variable ceases to exist, and the program's behavior is undefined.
So don't do that.
Upvotes: 2
Reputation: 36049
Both arrays are local to the statement expressions, and the memory they occupy can be reused after the end of the expression. In this case, it is reused.
If you would access or use these pointer's values, you would be invoking undefined behaviour, so their equality is of no consequence.
Upvotes: 2