(a == 1 && a == 2 && a == 3)はCやC ++で真と評価できるのでしょうか。

Java </で可能です。 a>および JavaScript

But the question is, can the condition below ever evaluate to true in C or C++?

if(a==1 && a==2 && a==3) 
    printf("SUCCESS");

編集

a整数の場合

0
nl ru de
@qrdl Cは未定義の動作をしますか?私はその言語にあまり精通していませんが、私はそれがしたと思いました。もしそうであれば、 a が未初期化の int である場合などに起こります。
追加された 著者 François Andrieux,
@qrdl私はC標準のコピーを持っていません、そして私はCの専門家ではありません。私がリンクした答えが言うことを繰り返します、そしてそれを 引用します。値に register ストレージがある場合、それは未定義の動作になる可能性があると主張しています。あなたはここではなくそこでそれを主張することができます、私はその答えが言うことを超えて追加するものは何もありません、しかしそれはここの誰かがそれを読むのを煩わしたようには見えません。
追加された 著者 François Andrieux,
a の種類によって異なります。 bool operator ==(int)const {trueが返されます。 あるいは、あなたがたまたま未定義の振る舞いをしているなら、何でも起こり得る。
追加された 著者 François Andrieux,
@LightnessRacesinOrbitリンクされた回答では、整数のトラップ表現は言語で許可されているため、その値の初期化されていない値の読み取りは未定義の動作です。
追加された 著者 François Andrieux,
@qrdlそれについて読むと、言語は整数型のトラップ値を許しているので、それを読むのは実際に未定義の振る舞いです(この回答に基づく) a>)。
追加された 著者 François Andrieux,
@LightnessRacesinOrbit この回答は、CでUBが使用されている理由を説明していますが、c ++で使用されている理由はさまざまです。値は実際には不定であり、いくつかの目的に使用できますが、直接読み取ることはできません。
追加された 著者 François Andrieux,
@LightnessRacesinOrbit私が理解していることから、Cではそれはある特定の自己矛盾がないが未知の値を持っていなければならないので、それは完全に未定義の振る舞いよりむしろいくつかの操作に対して不確定な振る舞いです。リンクされた答えはあなたが例えば記憶表現をコピーして調べることができると主張します。結果は予測できませんが、コードはまだ意味があり、必ずしもUBに分類されるわけではありません。私はCのエキスパートではないので、私は間違っているかもしれませんが、それは私がこれまで読んだことの解釈です。
追加された 著者 François Andrieux,
@FrançoisAndrieux値が不定の場合は、定義上、固定の既知の値がないため、比較結果は確実に経時的に変化します。しかし、これがUBではない場合は問題ありません。実際には、それが起こる理由は想像できません(積極的な最適化がこのUBを簡単に利用できるC ++とは異なります)。
追加された 著者 Lightness Races in Orbit,
繰り返しますが、トラップ値は不要で、UBも不要です。これらは気を散らすものです。唯一の関連する問題は、不確定値を比較することが時間の経過とともに予測通りに振る舞うかどうかということです。
追加された 著者 Lightness Races in Orbit,
@FrançoisAndrieuxそうですね。値が不定で、動作によっては動作が不定で、比較が含まれている場合、逐次比較では、明確に定義されていて有効であれば、必ず異なる結果が返されます。例えば a == 1 && a == 2 そのためにはUBは必要ないと思います。非決定論で十分です。確かに、それは非決定論が意味するものです!
追加された 著者 Lightness Races in Orbit,
@qrdl:そのことを言い表してもらえますか? C ++では、値は未定義であり、それを読むことはUBを持ちます。 Cがそれについてはっきりしていなくても私を驚かせることはありませんが、私はもっと聞くことに興味があります。
追加された 著者 Lightness Races in Orbit,
@EugeneSh。 a は整数ではなく、マクロです。ただし、整数に評価される式には拡張されますが、これは重要な場合もそうでない場合もあります。いずれにせよ、この質問は単に誰にも恩恵を与えないコード体操です。
追加された 著者 Lightness Races in Orbit,
他の質問によるマクロハックは、CとC ++の両方に当てはまります。
追加された 著者 Ben Voigt,
C11 6.7.9 10:自動保存期間を持つオブジェクトが明示的に初期化されていない場合、その値は不定です。 3.19.2:不定値:未指定値またはトラップ表現そうです、理論的にはtrap値を持つことができますが、たとえそれがあったとしても、3.19.5によるとtrapはそれ以上の操作が実行されないようにプログラムの実行を中断しますので比較はできません。できるでしょう。
追加された 著者 qrdl,
@FrançoisAndrieuxCにはUBがあります(実際にはたくさんあります)が、この場合はそうではありません。 a が単一化されている場合でも、予測不可能な値はありますが値は保持されているため、この値を他の値と比較することは明確に定義されています。もちろん他の人が示唆しているように、いくらかのプリプロセッサ乱用があります
追加された 著者 qrdl,
a にトラップ値がある場合、動作は明確に定義されています - プログラムを中断します。 a に他の値がある場合、この値を使用してもUBにはなりません
追加された 著者 qrdl,
@MaxLanghofコンパイラは、最適化されているかどうかにかかわらず、C標準に違反する権利はありません。さらに、 avolatile と宣言されていない限り、スマートコンパイラは if 全体を最適化します。
追加された 著者 qrdl,
複製として再度開くための投票は、現在のフォームの質問には答えず、C ++にのみ適用されます。
追加された 著者 Eugene Sh.,
重複する質問には、C ++にのみ当てはまる回答があります。私はそれを閉じないで、むしろCにそれを狭めるでしょう。
追加された 著者 Eugene Sh.,
あるハードウェアカウンタにマッピングされている場所で a がどういうわけか volatile として定義されていて、それぞれの読み取りが増加している、もう一つの完全に合法的なケースを考えることができます。リンカの魔法なしに変数を特定のアドレスにマッピングするのは簡単ではないということです。
追加された 著者 Eugene Sh.,
@LightnessRacesinOrbitそれについて議論していません。
追加された 著者 Eugene Sh.,
#define a(x ++)、次に int x = 1;
追加された 著者 Eugene Sh.,
@qrdlコンパイラの最適化が行われていない場合にのみ、引数は真実になります。私はC標準についても全く知りませんが、私はあなたの主張が正当化されることを強く疑います。
追加された 著者 Max Langhof,
さらにコードを追加する必要があります。 a とは一体何なのでしょうか。
追加された 著者 Michi,
@TimRandall他の質問を見て、これがCまたはC ++でどのように機能するかについて非常に興味がありました。
追加された 著者 WEB_UI,
しかし、なぜ?なぜこの質問をするのですか?これが起こった特定のテストケースはありましたか、それともなぞなぞですか。
追加された 著者 Tim Randall,
#define if()if(1)または、さらに詳細には #define if()
追加された 著者 Blaze,

4 答え

If a is of a primitive type (i.e all == and && operators are built in) and you are in defined behavior, and there's no way for another thread to modify a in the middle of execution (this is technically a case of undefined behavior - see comments - but I left it here anyway because it's the example given in the Java question), then I don't believe there is anything way for this to evaluate to true. However, as you can see by that list of conditions, there are many scenarios in which that expression could evaluate to true, depending on the types used and the context of the code.

5
追加された
スレッドが実行の途中で値を変更する可能性があり、 a がプリミティブ型である場合は、未定義の動作になります。そのため、以前の定義済み動作の状態がすでにその状態をカバーしています。
追加された 著者 François Andrieux,
@MaxLanghofいいえ、でもその場合それは書き込みをしている別のスレッドではなく、とにかく冗長な条件でカバーされないでしょう。編集: volatile を使用して、マップされたハードウェアデバイスではなく別のスレッドとの競合状態を解消しようとする場合は、この回答は、 volatile が競合状態を妨げない理由です。
追加された 著者 François Andrieux,
実行中に a を変更することは必ずしもUBではありません。 volatile ケースについての私の答えを見てください。
追加された 著者 Eugene Sh.,
@FrançoisAndrieuxaが volatile int (そして何らかの外部ハードウェアによって書き込まれる)の場合も同様ですか?
追加された 著者 Max Langhof,
@FrançoisAndrieux私はあなたがここにいると仮定するつもりです、私は論争するUBについて十分に知りません。
追加された 著者 Nick Mertin,

「aは整数」の定義によります。

int a__(){ static int r; return ++r; }
#define a a__()  //a is now an expression of type `int`
int main()
{
    return a==1 && a==2 && a==3; //returns 1
}

もちろん:

int f(int b) { return b==1&&b==2&&b==3; }

常に 0; が返され、オプティマイザーは通常、チェックをそのとおりに置き換えます。

3
追加された

Cでは、はい、できます。 a が初期化されていない場合(こちらで説明したように、UBがない場合でも)、値は不定です、それを読むことは不確定な結果を与えます、そしてそれを他の数と比較することはまた不確定な結果を与えます。

直接的な結果として、 atrue1 を一度に比較し、次に trueを比較できます。 2 代わりに次の瞬間に。両方の値を同時に保持することはできませんが、その値は不定であるため問題にはなりません。

実際には、2つの比較の間に実際のストレージがメモリ内で変化するのには実際の理由がないため、説明した動作を見て驚きます。


C ++では、のようなものです。上記はまだそこには当てはまりますが、C ++では不定値を読み取ることは常に未定義の操作であるため、実際にはすべての賭けが無効になっています。

オプティマイゼーションはあなたのコードを積極的に卑劣化することを許されています。

したがって、CよりもC ++でこの結果を見てもそれほど驚くことではありませんが、動作を定義していないプログラムはいずれにせよ完全に無視されるので、目的や意味のない観察です。


そして当然ながら、どちらの言語でも #define a(x ++)のような "トリック"がありますが、これらはあなたの質問の精神には含まれないようです。

2
追加された
それが私が言おうとしていたことです。 Cでは、値は未定義の初期値に固定されていることを理解しています。C++の場合とは異なり、自己矛盾のないものにする必要があります。
追加された 著者 François Andrieux,
@FrançoisAndrieux不確定で自己矛盾がないという考えは、反対の表現を見つけられない限り、私の考えでは完全に相反します。不定は不定を意味します。決定論的な価値があるかないか(私たちがそれを守ることが許されているかどうかは別としても)
追加された 著者 Lightness Races in Orbit,
@ qrdlいいえ、値は不定です。決定的な価値がないというもう一つの英語の言い方です。不確定は「任意」、「ランダム」、「置き去り」を意味するのではなく、不確定を意味します。
追加された 著者 Lightness Races in Orbit,
@ qrdl私には不合理な言葉のようです。もしそれが真であれば、不確定な値は確定的な値と同じようになるでしょう。それでそれを不確定と呼ぶことのポイントは何ですか。すみませんが、私はあなたが「不確定」を弄っているとは思いません。しかし、私はC言語の弁護士としての経験が弱いことを認めているので、「不定」を「不定」にするのではなく、「不定」を意味するC固有のことが足りないのかもしれません。 C用語で "不確定"を定義することによって?
追加された 著者 Lightness Races in Orbit,
その値は不定です、それを読むと不定の結果が得られますそれはいくつかの価値があり、それは読まれるでしょう
追加された 著者 qrdl,
@LightnessRacesinOrbit値は不定ですが、この値にアクセスすることは他の値にアクセスすることと同じなので、結果は明確に定義されています。
追加された 著者 qrdl,

マクロマジックを脇に置くと、この質問に積極的に答えることができる一つの方法を見ることができます。 __attribute __((at(ADDRESS))); 属性を使用できるようにする拡張機能があるとしましょう。 location(ARM GCCなど、一部のARMコンパイラで使用可能)アドレス ADDRESS にハードウェアカウンタレジスタがあり、これが各読み取りを増加させているとしましょう。それから私達はこのようなことをすることができます:

volatile int a __attribute__((at(ADDRESS)));

volatile は、比較が行われるたびにコンパイラーにレジスター読み取りを生成させるため、カウンターは3倍になります。カウンタの初期値が 1 の場合、ステートメントはtrueを返します。

P.S at 属性が気に入らない場合は、 a を特定のメモリセクションに配置することで、リンカスクリプトを使用して同じ効果を得ることができます。

2
追加された