タグ付けされた質問 「language-lawyer」

プログラミング言語と環境の正式または信頼できる仕様の複雑さについての質問。

13
最適化されない無限の空のループを作成するにはどうすればよいですか?
C11標準は、定数制御式を含む反復ステートメントを最適化してはならないことを示唆しているようです。私はこの回答から私のアドバイスを取り入れています。これは、ドラフト標準のセクション6.8.5を具体的に引用しています。 制御式が定数式ではない反復文...は、実装によって終了するものと想定されます。 その答えでは、ループのようなループwhile(1) ;は最適化の対象とすべきではないと述べています。 では、なぜClang / LLVMは(でコンパイルされたcc -O2 -std=c11 test.c -o test)以下のループを最適化するのですか? #include <stdio.h> static void die() { while(1) ; } int main() { printf("begin\n"); die(); printf("unreachable\n"); } 私のマシンでは、これはを出力しbegin、次に不正な命令(のud2後にトラップが配置されたdie())でクラッシュします。godboltでは、の呼び出し後に何も生成されないことがわかりputsます。 Clangに無限ループを出力させるのは意外と難しい作業でし-O2たが、volatile変数を繰り返しテストすることはできましたが、これには不要なメモリ読み取りが含まれています。そして、私がこのようなことをした場合: #include <stdio.h> static void die() { while(1) ; } int main() { printf("begin\n"); volatile int x = 1; if(x) die(); …


5
Doubleの「==」演算子の定義
なんらかの理由で、クラスの.NET Frameworkソースに潜入しDoubleていて、の宣言==が次のとおりであることがわかりました。 public static bool operator ==(Double left, Double right) { return left == right; } 同じロジックがすべてのオペレーターに適用されます。 そのような定義のポイントは何ですか? どのように機能しますか? なぜ無限再帰を作成しないのですか?
126 c#  .net  language-lawyer 


2
ラムダキャプチャと同じ名前のパラメータ-誰が他をシャドウしている?(clangとgcc)
auto foo = "You're using g++!"; auto compiler_detector = [foo](auto foo) { std::puts(foo); }; compiler_detector("You're using clang++!"); clang ++ 3.6.0以降では「clang ++を使用しています!」と出力されます。キャプチャ fooが使用されていないことを警告します。 g ++ 4.9.0以降では、「あなたはg ++を使用しています!」と出力します。パラメータ fooが使用されていないことを警告します。 ここでC ++標準に正確に準拠しているコンパイラはどれですか? ワンドボックスの例

6
ラムダが自分自身を返す:これは合法ですか?
このかなり役に立たないプログラムを考えてみましょう: #include <iostream> int main(int argc, char* argv[]) { int a = 5; auto it = [&](auto self) { return [&](auto b) { std::cout << (a + b) << std::endl; return self(self); }; }; it(it)(4)(6)(42)(77)(999); } 基本的に、自分自身を返すラムダを作成しようとしています。 MSVCはプログラムをコンパイルし、実行します gccはプログラムをコンパイルし、segfaultします clangは次のメッセージでプログラムを拒否します。 error: function 'operator()<(lambda at lam.cpp:6:13)>' with deduced return type cannot …

3
if(0)を使用して、動作するはずのスイッチのケースをスキップしていますか?
C ++のswitchステートメントの2つのケースで、両方とも3番目のケースに分類したいという状況があります。具体的には、2番目のケースは3番目のケースにフォールスルーし、最初のケースも2番目のケースを通過せずに3番目のケースにフォールスルーします。 私はばかげた考えを持っていて、それを試しました、そしてそれはうまくいきました!2番目のケースをif (0) {...で包みました}。次のようになります。 #ifdef __cplusplus # include <cstdio> #else # include <stdio.h> #endif int main(void) { for (int i = 0; i < 3; i++) { printf("%d: ", i); switch (i) { case 0: putchar('a'); // @fallthrough@ if (0) { // fall past all of case 1 (!) …

2
nullインスタンスでメンバー関数を呼び出すと、未定義の動作が発生するのはいつですか?
次のコードを検討してください。 #include <iostream> struct foo { // (a): void bar() { std::cout << "gman was here" << std::endl; } // (b): void baz() { x = 5; } int x; }; int main() { foo* f = 0; f->bar(); // (a) f->baz(); // (b) } nullポインターに(b)対応するメンバーがないため、クラッシュすることが予想されxます。実際に(a)は、thisポインタは使用されないため、クラッシュしません。 ので(b)逆参照thisポインタ((*this).x = 5;)、およびthisnullであるヌルを逆参照することは、常に未定義の動作と言われているように、プログラムは、未定義の動作に入ります。 (a)未定義の動作につながりますか?両方の関数(およびx)が静的である場合はどうなりますか?

5
カンマ付きの三項演算子が真の場合に1つの式しか評価しないのはなぜですか?
私は現在、C ++ Primerという本を使ってC ++を学んでいます。本の演習の1つは次のとおりです。 次の式の意味を説明してください。 someValue ? ++x, ++y : --x, --y 私たちは何を知っていますか?三項演算子はコンマ演算子よりも優先順位が高いことがわかっています。2項演算子を使用すると、これは非常に簡単に理解できましたが、3項演算子を使用すると、少し苦労します。二項演算子で「優先順位が高い」とは、式の前後に優先順位の高い括弧を使用できることを意味し、実行は変更されません。 三項演算子の場合は、次のようにします。 (someValue ? ++x, ++y : --x, --y) コンパイラーがコードをグループ化する方法を理解するのに私を助けない同じコードを効果的にもたらします。 ただし、C ++コンパイラでのテストから、式がコンパイル:されることがわかり、演算子自体が何を表すことができるかわかりません。したがって、コンパイラーは三項演算子を正しく解釈するようです。 次に、2つの方法でプログラムを実行しました。 #include <iostream> int main() { bool someValue = true; int x = 10, y = 10; someValue ? ++x, ++y : --x, --y; std::cout << …

2
3つの主要なC ++コンパイラでコンパイルが異なるプログラム。どちらが正しいですか?
前の質問の興味深いフォローアップとして(ただし、実用的にはそれほど重要ではありません)、 C ++では、変数を宣言するときに変数名を括弧で囲むことができるのはなぜですか。 括弧内の宣言と注入されたクラス名機能を組み合わせると、コンパイラの動作に関して驚くべき結果になる可能性があることがわかりました。 次のプログラムを見てください。 #include <iostream> struct B { }; struct C { C (){ std::cout << "C" << '\n'; } C (B *) { std::cout << "C (B *)" << '\n';} }; B *y = nullptr; int main() { C::C (y); } g ++ 4.9.2でコンパイルすると、次のコンパイルエラーが発生します。 main.cpp:16:10: error: cannot …

8
C ++でCヘッダーを使用する場合、std ::またはグローバル名前空間の関数を使用する必要がありますか?
Cは、正確ではありませんが、C ++のサブセットです。そのため、名前を少し(stdio.hto cstdio、stdlib.hto cstdlib)変更することで、C ++でほとんどのC関数/ヘッダーを使用できます。 私の質問は、実際には一種の意味論です。C ++コード(GCCコンパイラの最新バージョンを使用)では、呼び出すことができますがprintf("Hello world!");、std::printf("Hello world!");まったく同じように機能します。そして、私が使用しているリファレンスでは、としても表示されstd::printf("Hello world!");ます。 私の質問は、std::printf();C ++で使用する方が良いですか?違いはありますか?
113 c++  language-lawyer  std 

8
「コールバック地獄」とは何ですか?RXはそれをどのように、そしてなぜ解決するのですか?
JavaScriptとnode.jsを知らない人のための「コールバック地獄」とは何かを説明する簡単な例とともに、明確な定義を誰かが提供できますか? 「コールバック地獄の問題」はいつ(どのような設定で)発生しますか? なぜそれが起こるのですか? 「コールバック地獄」は常に非同期計算に関連していますか? それとも、シングルスレッドアプリケーションでも「コールバック地獄」が発生するのでしょうか。 私はコースラでリアクティブコースを受講しました。彼の講義の1つで、エリックメイヤーはRXが「コールバック地獄」の問題を解決すると述べました。私はCourseraフォーラムで「コールバック地獄」とは何かを尋ねましたが、明確な答えがありませんでした。 簡単な例で「コールバック地獄」について説明した後、RXがその簡単な例で「コールバック地獄問題」をどのように解決するかを示すこともできますか?

2
C ++ 20は、ファイルに格納されるソースコードを義務付けていますか?
しかし、少し奇妙な質問ですが、私が正しく覚えていれば、C ++ソースコードでは、ファイルシステムにファイルを格納する必要はありません。 カメラを介して手書きの紙をスキャンするコンパイラーがあれば、適合実装になります。実際にはそれほど意味がありませんが。 ただし、C ++ 20はでソースの場所を追加しfile_nameます。これは、ソースコードを常にファイルに保存する必要があることを意味しますか?

9
新しい標準バージョンのC ++でサイレント動作の変更があったことはありますか?
(リストではなく、要点を証明するための例を1つか2つ探しています。) C ++標準の変更(たとえば、98から11、11から14など)によって、既存の整形式の定義された動作のユーザーコードの動作がサイレントに変更されたことがありますか?つまり、新しい標準バージョンでコンパイルするときに警告やエラーはありませんか? ノート: 私は、実装者/コンパイラの作成者の選択ではなく、標準で義務付けられている動作について質問しています。 コードの工夫が少ないほど、(この質問への回答として)優れています。 のようなバージョン検出を備えたコードを意味するのではありません#if __cplusplus >= 201103L。 メモリモデルに関する回答は問題ありません。

2
事実上最終対最終-異なる動作
これまでのところ、実質的にfinalとfinalはほぼ同等であり、JLSは、実際の動作が同一でなくても、それらを同様に扱うと思いました。それから私はこの不自然なシナリオを見つけました: final int a = 97; System.out.println(true ? a : 'c'); // outputs a // versus int a = 97; System.out.println(true ? a : 'c'); // outputs 97 どうやら、JLSはここで2つの間に重要な違いをもたらし、その理由はわかりません。 私は次のような他のスレッドを読みました 最終と事実上最終の違い 事実上最終変数と最終変数 「事実上最終的」である変数はどういう意味ですか? しかし、それらはそのような詳細には入りません。結局のところ、より広いレベルでは、それらはほとんど同等であるように見えます。しかし、深く掘り下げると、明らかに異なります。 この動作の原因は何ですか?誰かがこれを説明するいくつかのJLS定義を提供できますか? 編集:私は別の関連するシナリオを見つけました: final String a = "a"; System.out.println(a + "b" == "ab"); // outputs true // …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.