問題タブ [sequence-points]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 式a=a + b-(b = a)がc ++でシーケンスポイント警告を出すのはなぜですか?
テストコードは次のとおりです。
これをコンパイルすると、次の警告が表示されます。
操作を未定義にできるのはなぜですか?
私の理解によれば、(b = a)
()の優先順位が高いため、最初に部分式を評価する必要があります。したがって、b=aに設定します。次に、「+」と「-」の優先順位が同じであるため、式は左連想的に評価されます。したがって、a + b
次に評価する必要があり、最後にの結果を(b = a)
から差し引く必要がありますa + b
。ここでは、シーケンスポイントルールに違反していることはわかりません。
c - 割り当てとシーケンス ポイント: これはどのようにあいまいですか?
C コードを考えてみましょうa = a = a
。代入のためのシーケンス ポイントがないため、このコードは での未定義の操作についてコンパイル時に警告を生成しa
ます。
a
ここで可能な値は何ですか? a
値を変更することはできなかったようです。ここに実際に未定義の動作がありますか、それともコンパイラが単に怠けているだけですか?
c++ - オブジェクトを返す関数呼び出しとそのオブジェクトのメソッド呼び出しの間にシーケンスポイントはありますか?
私が書く場合、私は評価の前にf(x)->g(args, ...)
シーケンスポイントに頼ることができますか?私は両方の方法で議論を見ることができます:f(x)
args, ...
- §1.9.17「関数を呼び出す場合(関数がインラインであるかどうかに関係なく)、すべての関数の引数(存在する場合)の評価後、関数本体の式またはステートメントの実行前に実行されるシーケンスポイントがあります。戻り値のコピー後、関数外の式の実行前にもシーケンスポイントがあります。」
- 一方、オブジェクトポインタは、
this
私が書いたかのように暗黙的に非表示の引数g(f(x), args, ...)
であり、引数のようなものであり、したがって指定されていないことを示唆しています。
->
演算子は通常の二項演算子ではありません。これは、私が書いた場合のように、以前は明らかに評価できg(...)
ないためです。私はそれについての特定の声明を見つけることができないことに驚いています。f(x)
f(x) + g(...)
c - returnステートメントの後のシーケンスポイント?
ここでの質問に対する私の答えでは、return
ステートメントと同じ行のグローバル変数で接尾辞++が使用されたときに何が起こったのかを説明しました。
C11の有益な付録Cは、aの直後にシーケンスポイントがあり、シーケンスポイントreturn
に関するテキストが見つからない規範的な第6.8.6.4章を参照していると述べています。
return
C標準のどこに、ステートメントの後にシーケンスポイントがあることを示す規範的なテキストを見つけることができますか?
(私は、特別な場合として、7.1.4 / 3で、ライブラリ関数についてこれを示す規範的なテキストのみを見つけました。)
c++ - 新しいマップ要素にインデックスを付けて、それを読み取る何かをそれに割り当てて、未定義の動作をしているのか、それとも単に未指定なのか?
この質問に答えた後、問題のコードが未定義の動作であるかどうかについて長い議論がありました。コードは次のとおりです。
まず第一に、これが少なくとも特定されていないことは確立されていました。結果は、割り当てのどちら側が最初に評価されるかによって異なります。私の回答では、結果として得られた 4 つのケースのそれぞれについて、どちらの側が最初に評価されるか、および要素がこれより前に存在するかどうかの要因を追跡しました。
同様に出てきた短い形式がありました:
私はそれがもっとこのようなものだと主張しました:
最終的に、私にとってうまくいくと思われる例を見つけました:
元に戻って、簡単に理解できるように、関連する関数呼び出しに分割しました。
word_count["a"]
が存在しない場合は、間に順序付けなしで 2 回割り当てられると主張されました。私が真実だと思っていた2つのことが実際にあった場合、私は個人的にそれがどのように起こるかわかりませんでした:
サイドが評価のために選ばれるとき、反対側が開始する前に、サイド全体が評価されなければなりません。
word_count["a"] = 1 などの構成要素は、要素が挿入されてから割り当てられた場合でも、明確に定義された動作を示します。
これらの 2 つのステートメントは本当ですか? 最終的に、それは実際には未定義の動作ですか? もしそうなら、なぜ 2 番目のステートメントが機能するのですか (機能すると仮定して)? 2 番目が false の場合、myMap[i]++;
世界中のすべての s は形式が正しくないと思います。
役立つリンク:未定義の動作とシーケンス ポイント
c - int a=1, b=a++; を行います。未定義の動作を呼び出しますか?
int a=1, b=a++;
未定義の動作を呼び出しますか? a
の初期化と、そのアクセスと の初期化子での変更の間に介在するシーケンス ポイントはありませんがb
、私が知る限り、初期化はオブジェクトの「変更」ではありません。オブジェクトの「初期値」を与えるために初期化子が指定されます。6.7.8 初期化、パラグラフ 8:
初期化子は、オブジェクトに格納される初期値を指定します。
そして、オブジェクトへのアクセスの前に順序付けされたものとして「初期」を取るのが妥当と思われます。この問題は以前に検討されたことがあり、受け入れられた解釈はありますか?
c - 「int a=4,*ptr=&a;」のようなステートメントに「シーケンスポイント」の問題がありますか? または "x+=4,y=x*2;"?
シーケンス ポイント全体に対する私の理解は基本的なものです。私が持っているのは、「シーケンスポイントに遭遇すると、以前の評価のすべての副作用が完全であることを確認できる」という大雑把な直感的な考えだけです。また、動作が未定義のようなステートメントでprintf("%d",a++,++a,a++)
は、カンマはシーケンスポイントを意味しないのに対し、セミコロンは意味することも読みました。ですから、推測して直感に頼るのではなく、これに対する非常に厳密で決定的な答えが大いに役立つと感じています。
したがって、C では次のようなステートメントは安全で確実です。
はいの場合、どのように?特に 2 番目のケースで、コンマがシーケンス ポイントでない場合、代入で使用する前に、コンマがx
増加したことをどのように確認できますか? 最初のステートメントでは、アドレスを に割り当てる前に、 が初期化され、メモリが割り当てられていることをどのように確認できますか? 安全にプレイして、上記に次を使用する必要があります。4
y=x*2
a
ptr
と
編集コンマ演算子についての私の理解は、それらのステートメントが安全であることを教えてくれます。しかし、シーケンスポイントとそのようなものがどのようprintf("%d",a++,++a,a++)
に定義されていないかについて読んだ後、私は考え直しました。
c - さらに別のシーケンス ポイント クエリ: *p++ = getchar() はどのように機能しますか?
例 7 式のグループ化は、その評価を完全には決定しません。次のフラグメントでは:
式ステートメントは、次のように記述されているかのようにグループ化されます。
ただし、 p の実際のインクリメントは、前のシーケンス ポイントと次のシーケンス ポイント ( ; ) の間の任意の時点で発生する可能性があり、 getchar への呼び出しは、その戻り値が必要になる前の任意の時点で発生する可能性があります。
したがって、基本的には、これを未指定の動作として理解しています-いずれか*p = getchar(); p++;
またはp++; *p = getchar()
。;
はシーケンス ポイントを意味しますが、式全体に他のシーケンス ポイントがないことに注意してください。
したがって、この構文は役に立ちません。そして、ほとんどの場合、ポインタ代入の ++ と -- は役に立ちません。右?
c - "for(i=1;i<=10;printf("%d\n";i),i++) のようなものは C で有効で UB フリーですか?
次の 2 つのコード ブロックはまったく同じで、同じことを実現していますか?プログラムを実行すると同じことが表示されますが、厳密な説明をいただければ幸いです。
と
ループはfor
引数として有効な C ステートメントを期待していますね。しかし、x+=4,y=x*2;
ここではコンマがシーケンス ポイントとして機能するため、次のようなステートメントが安全であることを StackOverflow で確認しましたが、上記のループprintf("%d\n",i),i++)
で引数として渡されたステートメントについても同じ真実ですか?for
はいの場合は、そこから生じる小さな質問に答えてください。
comma
コンマで区切られた多数のステートメントを含むステートメントでシーケンス ポイントとして機能しますか?以下のような関数呼び出し:
printf("Enter number\n"),scanf("%d",&number),printf("You entered %d",number);