C99§6.5.2.2p5 有一个小 gem ,我加粗以强调这个问题:



这允许我们返回 structs ,例如:

struct foo { int foo;
             char bar[2]; };

struct foo get_foo() {
    struct foo return_value = { .foo = 42,
                                .bar = "x" };
    return return_value;
}

...并从调用者内部的其他地方分配该返回值,例如:
int main(void) {
    struct foo bar = get_foo(); /* Well defined because the return value
                                 * is copied -before- the sequence point
                                 * that terminates its storage duration */
    printf("%s\n", bar.bar);
    printf("%d\n", get_foo().foo); /* Again, well defined because the access
                                    * occurs before the next sequence point
                                    * (the function call). */
}

...同时呈现以下示例无效:
int main(void) {
    printf("%s\n", get_foo().bar); /* UB because there's a sequence point
                                    * between the evaluation of the sub-
                                    * expression `get_foo().bar` and the
                                    * entrace to the function `printf` */
    get_foo().bar[0]++; /* UB because an attempt is made to modify the
                         * result of a function call */
}

——

然而,C11§6.5.2.2p5 本质上是相同的段落,但没有粗体文​​本。



上面那些在 C99 中未定义行为的示例在 C11 中是否仍然未定义?如果是这样,哪些段落使它们无效?如果没有,我认为返回的自动值/对象的存储持续时间必须有所延长;标准的哪一部分规定了存储期限的延长?

最佳答案


上面提出的定义明确的例子仍然是明确定义的。
这个对象的临时生命周期“在包含完整表达式或声明符的评估结束时结束”,所以这个以前未定义的例子现在已经很好地定义了:

printf("%s\n", get_foo().bar);
此示例仍然是未定义的行为,因为尝试修改具有临时生命周期的对象:
get_foo().bar[0]++;

正如 Jens Gustedt 在评论中指出的那样,C11§6.2.4p8 似乎传达了与 C99§6.5.2.2p5 包含 C11§6.5.2.2p5 省略的句子略有不同的含义:

似乎进行了一些重组; C99 中的“存储持续时间扩展”语句已更改,从“函数调用”部分移至“存储持续时间”部分,在那里更合适。
剩下的唯一问题是函数调用的结果是否被视为左值。对于每个产生左值的运算符,似乎都明确提到该运算符产生左值。例如,C11§6.5.3.2p6 声明一元 * 运算符产生一个左值,提供它的操作数指向一个对象。
然而,函数调用运算符并没有说明产生一个左值,所以我们必须假设它不产生一个左值。如果这还不够好,那么考虑 C11§6.5.2.3p3 和 p7,它们说:

我们还可以从这两段推导出函数的结果不是左值,因此满足 C11§6.2.4p8(上面引用的)的标准。
脚注 95 很有趣,但与手头的讨论无关:

关于c - 在 C11 中是否未定义修改函数调用的结果,或者在下一个序列点之后访问它?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31128852/

10-16 01:27