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

时间:2011-11-05 07:37:54

标签: c language-lawyer sequence-points

结构成员初始化表达式之间是否有一个序列点?

例如,是否明确定义下面的代码将始终打印“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;
}

3 个答案:

答案 0 :(得分:6)

我认为§6.7.8-23解决了这个问题:

  

初始化列表中出现任何副作用的顺序   表达式没有特别说明。

关于复合文字:

  

§6.5.2.5-7

     

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

答案 1 :(得分:2)

我认为C99 TC2(n1124)中的相关措辞见§6.7.8/ 23:

  

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

脚注说:

  

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

答案 2 :(得分:1)

没有。您可以在C标准的附录C(或草案n1256,n1516等)中亲自了解。

每个完整声明符后面都有一个序列点,在初始化中使用&&或调用函数的表达式中仍然会有序列点。

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

func(getc(), getc()); // who knows what order?