Muhammad Hewedy
Muhammad Hewedy

Reputation: 30058

GCC Statement Expression Issue

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

Answers (3)

celtschk
celtschk

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

Keith Thompson
Keith Thompson

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 objectarr` 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

thiton
thiton

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

Related Questions