我很困惑N2346::6.5.2.5/15
,N2346::6.5.2.5/16
哪些州(雇员。我的)
15 示例 8 每个复合文字只在给定范围内创建一个对象
struct s { int i; }; int f (void) { struct s *p = 0, *q; int j = 0; again: q = p, p = &((struct s){ j++ }); if (j < 2) goto again; return p == q && q->i == 1; }
函数 f() 总是返回值 1。
16 请注意,如果使用迭代语句而不是显式 goto 和标记语句,则未命名对象的生命周期将仅是循环的主体,并且在下次进入时 p 将具有不确定的值,这将导致在 未定义的行为中。
在我看来,这句话与标准的另一部分相矛盾。恰恰:
N2346::6.5.2.5/5
如果复合文字出现在函数体之外,则该对象具有静态存储持续时间;否则,它具有与封闭块关联的自动存储持续时间。
这意味着使用复合文字创建的块范围对象具有自动存储持续时间。
N2346::6.8/3
(雇员我的):
具有自动存储持续时间的对象的初始值设定项,以及具有块范围的普通标识符的可变长度数组声明符,每次声明时都会被评估并将值存储在对象s 中(包括在没有初始值设定项的对象中存储不确定值)是按 执行顺序到达的,就好像它是一个语句,并且在每个声明中按照声明符出现的顺序。
因此,即使goto
示例中的语句N2346::6.5.2.5/15
被替换为迭代语句,复合文字创建的对象也应该在每次到达时重新创建。
问题:为什么用goto
迭代语句替换会产生 UB?我的推理有什么问题?