C11与C99中临时物体的寿命

问题描述 投票:18回答:1

我试图破译导致C99和C11之间发生变化的a note。该说明中提出的修改最终以C11的6.2.4:8结束,即:

具有结构或联合类型的非左值表达式,其中结构或联合包含具有数组类型的成员(包括,递归地,所有包含的结构和联合的成员)是指具有自动存储持续时间和临时生存期的对象。它的生命周期在评估表达式时开始,其初始值是表达式的值。当包含完整表达式或完整声明符的评估结束时,它的生命周期结束。任何使用临时生命周期修改对象的尝试都会导致未定义的行为。

我理解为什么需要改变(有些讨论可以找到here。注意讨论可以追溯到C11之前)。然而,我不明白的是克拉克·尼尔森写下他的笔记时所说的一句话:

请注意,此方法另外声明了一个这样的示例,它符合C99,是不符合要求的:

struct X { int a[5]; } f();
int *p = f().a;
printf("%p\n", p);

我理解为什么这个例子在C11下是不符合的。我特别不明白的是它是如何符合C99的。并且,如果它是在C99下定义的,它应该做什么,定义打印悬空指针的值?

c c99 c11
1个回答
8
投票

我的理解是,在C99中,对象的最佳生命周期是块。因此,虽然6.5.2.2(以及您提到的注释中提到的其他一些§)明确指出您无法在下一个序列点之后访问返回值,但从技术上讲,它的地址在您离开封闭块之后才是不确定的(为什么你应该为一个无法访问的对象保留一些存储空间的原因留给读者一个练习)。因此,像

struct X { int a[5]; } f();
int *p;
{ p = f().a; }
printf("%p\n", p);

在C99和C11中未定义。在C11中,C99中不存在的“临时生命周期”概念允许在完整表达式结束后立即认为指针变得不确定。

© www.soinside.com 2019 - 2024. All rights reserved.