8

结构成员初始化表达式之间是否存在序列点?

例如,是否明确定义下面的代码将始终打印“a,b”?

#include <stdio.h>

typedef struct {
    char *bytes;
    int position;
    int length;
} Stream;

typedef struct {
    char a;
    char b;
} Pair;

char streamgetc(Stream *stream) {
    return (stream->position < stream->length) ? stream->bytes[stream->position++] : 0;
}

int main(void) {
    Stream stream = {.bytes = "abc", .position = 0, .length = 3};
    Pair pair = {.a = streamgetc(&stream), .b = streamgetc(&stream)};
    printf("%c, %c\n", pair.a, pair.b);
    return 0;
}
4

3 回答 3

6

我认为§6.7.8-23解决它:

未指定初始化列表表达式中任何副作用发生的顺序。

关于复合文字:

§6.5.2.5-7

6.7.8 中初始化列表的所有语义规则和约束都适用于复合文字。

于 2011-11-05T07:47:44.343 回答
2

我相信 C99 TC2 (n1124) 中的相关措辞在 §6.7.8/23 中:

在初始化列表表达式中出现任何副作用的顺序是未指定的131

脚注说:

131) 特别是,评估顺序不必与子对象初始化的顺序相同。

于 2011-11-05T07:50:01.757 回答
1

不,您可以在 C 标准的附录 C(或草案 n1256、n1516 等)中亲自查看。

每个完整的声明符之后都有一个序列点,并且仍然会有来自使用&&或调用函数的初始化内部表达式的序列点。

函数参数之间也没有序列点。

func(getc(), getc()); // who knows what order?
于 2011-11-05T07:46:26.970 回答