简体   繁体   中英

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??

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);

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.

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 res2 and 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM