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 に答える