使用在指定初始化器中初始化的变量

Using variable being initialized in a designated initializer

我可以使用在指定初始化程序中初始化的变量吗?

考虑以下清单:

struct A {
    int a;
    int * const a_ptr;
};

struct A foo(int a) {
    struct A result = {
        .a = a,
        .a_ptr = &result.a
    };

    return result;
}

demo

我可以在此指定的初始化表达式中使用 result 吗?这种行为是否已定义?此代码可移植吗?

更新

糟糕,该示例包含潜在的堆栈损坏。清单应为:

struct A {
    int a;
    int * const a_ptr;
};

void foo(int a) {
    struct A result = {
        .a = a,
        .a_ptr = &result.a
    };

    bar(&result);
}

自己初始化就可以了。

在声明 result 时,其地址(以及其字段的地址)是常量。所以在 result.

的初始化器中使用 &result.a 是安全的

的一个问题是您要返回此结构的副本。此副本包含不再存在的局部变量的地址,因此尝试使用返回结构的 a_ptr 成员的值将触发 undefined behavior.

问题完全变了,这是我的新答案:

你的代码没问题,你可以检查一下,它不会在任何平台上断言。

您将指向局部变量 result 的指针传递给 bar。在 bar 中,局部变量仍然存在 p 指向该变量(结果)。因此 a_ptr 仍然指向 result.a.

但我只是想知道你在这里想要达到什么目的。

#include <assert.h>

struct A {
  int a;
  int* const a_ptr;
};    

void bar(struct A *p)
{
  assert(p->a_ptr == &p->a);
}    

void foo(int a) {
  struct A result = {
      .a = a,
      .a_ptr = &result.a
  };

  bar(&result);
}

int main()
{
  foo(2);
}

顺便说一句:

 struct A result = {
      .a = a,
      .a_ptr = &result.a
  };

相当于:

  struct A result;  
  result.a = a;
  result.a_ptr = &result.a;

但对于后者,您需要声明 int* a_ptr; 而不是 int* const a_ptr;