在没有变量的情况下访问返回联合的字段是否合法?

时间:2016-03-16 15:38:35

标签: c unions

我有一个返回union类型的函数。是否允许标准(C99)直接从调用访问返回值的字段而不将值复制到变量。这里有一个例子来说明我的意思:

union thinga { int integ; char arr[4]; };

union thinga f(void)
{
  union thinga t = {.integ = 1};
  return t;
}
int main(void)
{
   printf("thinga is %d\n", f().integ);
}

是否允许使用字段f().integ的通话?在我的示例中,它是union,但struct的问题是相同的。 我问这个问题,因为我清楚地记得Solaris上的gcc 3.3并不喜欢这个结构,并会像地狱一样警告。它的问题在于它必须在内部生成一个不可见的变量,以便能够访问structunion的字段。较新的编译器似乎不介意构造,但我想知道是否有隐藏的捕获(即undefined bevaviour,我没有想到。

编辑:好吧,看起来我的人为设计的例子有点过于简单了,并且通过将数组衰减的链接指向范围对象外的指针注意到评论者2501,让我们看看我们是否处于相同的情况我改变了一下我的代码。

 union thinga f(const char *val)
 {
   union thinga t = {.integ = 0};
   t.arr[0] = val[0];
   return t;
 }

 int main(void)
 {
     printf(" thinga.integ=%d .arr=%s\n", f("1").integ, f("1").arr);
 }

这种情况与arrays that are not lvalues and sequence point restrictionUndefined behavior: when attempting to access the result of function call中的情况相同吗? (返回的值显然是必要的deidennd(endiannes),但这不是问题)。

2 个答案:

答案 0 :(得分:3)

这是有效的,并且由c标准允许,并且此代码中没有未定义的行为。

编辑:对于代码段

 int main(void)
 {
     printf(" thinga.integ=%d .arr=%s\n", f("1").integ, f("1").arr);
 }  

f("1").arr引用了union的arr元素。由于arr是一个数组,并且根据C规则,在此上下文中,数组将衰减为指向其第一个元素的指针。由于t是函数的本地变量(一个自动局部变量,一旦函数返回就不再存在),访问arr元素将调用未定义的行为。

答案 1 :(得分:0)

这与

完全相同
printf("thinga is %d\n", (union thinga) {.integ = 1}.integ);

,这显然是明确定义的。