What is the lifetime of compound literals passed a

2019-01-20 08:57发布

This compiles without warnings using clang.

typedef struct {
  int option;
  int value;
} someType;

someType *init(someType *ptr) {
  *ptr = (someType) {
    .option = ptr->option | ANOTHEROPT,
    .value = 1
  };

  return ptr;
}

int main()
{
  someType *typePtr = init( &(someType) {
    .option = SOMEOPT
  });
  // do something else with typePtr
}
  1. Is this even valid C?

  2. If so: What is the lifetime of the compound literal?

2条回答
我只想做你的唯一
2楼-- · 2019-01-20 09:26

It's valid C in C99 or above.

C99 §6.5.2.5 Compound literals

The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

In your example, the compound literal has automatic storage, which means, its lifetime is within its block, i.e, the main() function that it's in.

Recommended reading from @Shafik Yaghmour:

  1. The New C: Compound Literals
  2. GCC Manual: 6.25 Compound Literals
查看更多
Root(大扎)
3楼-- · 2019-01-20 09:32

Yu Hao has answered with the standard, now some vulgarization.

Whenever you see a compound literal like:

struct S *s;
s = &(struct S){1};

you can replace it with:

struct S *s;
struct S __HIDDEN_NAME__ = {1};
s = &__HIDDEN_NAME__;

So:

struct S {int i;};
/* static: lives for the entire program. */
struct S *s = &(struct S){1};

int main() {
   /* Lives inside main, and any function called from main. */
   s = &(struct S){1};

   /* Only lives in this block. */
   {
       s = &(struct S){1};
   }
   /* Undefined Behavior: lifetime has ended. */
   s->i;
}
查看更多
登录 后发表回答