問題タブ [using-declaration]
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++ - struct と int の間の clang での再定義の不一致
次のプログラムは、clang でコンパイルしてもエラーになりません。
struct の代わりに int を使用すると、次のようになります。
このプログラムは、clang でコンパイルすると再定義エラーになります。
プログラム間の唯一の違いは、使用されるエンティティの種類 (struct または int) ですが、一方はエラーなしでコンパイルされ、もう一方は再定義エラーが発生します。
これはclangのバグを示していますか? たぶん、宣言の使用に関しては、再定義とは何かという標準があいまいです。しかし、コンパイラはその解釈を一貫して行うべきではありませんか?
プログラムは次の場所でコンパイルできます。
c++ - メンバー関数を定義するときのコンパイル エラー (GCC のみ)
次のプログラムは、MSVS、clang、および GCC でエラーなしでコンパイルされます。
それではメンバー関数を定義しましょう。今でも MSVS と clang でコンパイルできますが、GCC ではコンパイルできません:
GCC は次のエラー メッセージを表示します。
- prog.cc:5:22: エラー: 'void A::f()' の定義が 'A' を囲む名前空間にありません [-fpermissive]
何故ですか?これは GCC のバグですか?
プログラムの 2 番目のバージョンが C++ 標準の規則に違反している場合、どの規則に違反していて、MSVS と clang がその違反の診断メッセージを表示しないのはなぜですか?
これは、c++ 標準のあいまいさのケースですか?
エラー メッセージから、次のルールに違反していると GCC が誤って認識しているように見えます。
- http://eel.is/c++draft/class.mfct#2「クラス定義の外に現れるメンバー関数定義は、クラス定義を囲む名前空間スコープに現れるものとします。」
メンバー関数の定義はクラス定義内にあるため、この規則に違反することはありません。私の理論では、GCC はクラス A の宣言を混乱させます。クラス定義 class A { ... } を名前空間 Y に持つグローバル名前空間で、GCC にバグがあると思います。
GCC では、同じエンティティを宣言します。これは、プログラムの最初のバージョンでは、GCC でコンパイルするときに ::A を main の完全な型として使用できることを観察することで確認できます。MSVS も同様です。ただし、Clang では、異なるエンティティを宣言します。この違いは、c++ 標準のあいまいさが原因である可能性があります。このようなあいまいさにもかかわらず、私たちは明らかにhttp://eel.is/c++draft/class.mfct#2に違反していません。そのルールは非常に明確です。
関連する質問:宣言を使用する場合と同じスコープ内のクラス宣言は、GCC ではコンパイルされますが、MSVS ではコンパイルされません
c++ - using-declaration を使用して名前空間メンバーを定義しようとしています
次のプログラムを検討してください。C++ 標準に従って整形式かどうか (必要な標準の関連部分への参照):
コンパイラごとに異なる結果が得られます。バグレポートを提出する必要があるコンパイラを見つけようとしています。
Clang: 次のコンパイラ エラーが発生します: 名前空間 'N' に 'i' という名前のメンバーがありません
GCC および Visual C++ は、エラーなしでコンパイルします。
比較のために、次の例では 3 つのコンパイラすべてでコンパイラ エラーが発生します。
c++ - using-directive による using-declaration での名前検索
次のプログラムは、C++ 標準に従って整形式ですか、それとも整形式ではありませんか?
さまざまなコンパイラでさまざまな結果が得られます。
- Clang ( http://melpon.org/wandbox/permlink/c8vl7XbumyyS6vsw ): エラーはありません。
- GCC ( http://melpon.org/wandbox/permlink/immhNeWFCMcCA800 ): エラー: 'i' が宣言されていません。
このプログラムは、C++ 標準に従って整形式ですか、それとも整形式ではありませんか? C++ 標準への参照が必要です。
バグを報告する必要があるコンパイラを見つけようとしています。
c++ - 名前の宣言、名前の導入、エンティティの宣言の違い
C++11 標準から、§7.3.3[namespace.udecl]/1:
using 宣言は、using 宣言が現れる宣言領域に名前を導入します。
使用宣言:
using typename
opt ネストされた名前指定子 非修飾 ID;
using ::
非修飾 ID;
using宣言で指定されたメンバー名は、using宣言が現れる宣言領域で宣言されます。
using宣言が発生する宣言領域で宣言されている名前はどういう意味ですか?
これは、using 宣言が発生する宣言領域にその名前を導入することと同じ意味ですか?
また、名前を宣言することと、名前が示すエンティティを宣言することには違いがありますか?
例:
c++ - using-declarations を使用する場合、修飾されていない名前のルックアップはどのように機能しますか?
これは、C++ 標準に従って、整形式または整形式ですか?
Clang はそれを拒否し、GCC はそれを受け入れます。
[namespace.udir-6] ( http://eel.is/c++draft/basic.namespace#namespace.udir-6 ) によると:
名前検索で 2 つの異なる名前空間で名前の宣言が検出され、宣言が同じエンティティを宣言せず、関数も宣言されていない場合、その名前の使用は不適切です。
これをどのように解釈すべきでしょうか。各 using 宣言は [namespace.udecl]p1 ( http://eel.is/c++draft/namespace.udecl#1 )によって名前を宣言していることに注意してください。
using 宣言は、using 宣言が現れる宣言領域に名前を導入します。
using-declaration :ネストされた名前指定子の非修飾 IDを
using typename
選択します;
using宣言で指定されたメンバー名は、using宣言が現れる宣言領域で宣言されます。[ 注: 指定された名前のみがそのように宣言されています。using-declaration で列挙名を指定しても、using-declaration の宣言領域でその列挙子が宣言されません。— 終わりの注 ] using 宣言がコンストラクター ([class.qual]) を指定する場合、using 宣言が現れるクラス ([class.inhctor]) 内のコンストラクターのセットを暗黙的に宣言します。それ以外の場合、using-declaration で指定された名前は、別の名前空間またはクラスの一連の宣言の同義語です。
したがって、名前 i の 4 つの宣言があります。
これらのうち、非修飾名検索で検索されるのはどれi
ですかsizeof(i)
?
プログラムが整形式であるように、同じ名前空間 (グローバル名前空間) にあるusing M::i;
とだけを見つけますか?using N::i;
それとも、異なる名前空間にある と だけを見つけstruct i {};
てstatic int i = 1;
、プログラムの形式が正しくないのでしょうか?
または、他の代替手段がありますか?
c++ - 多重継承のあるプログラムと元の宣言とは異なるアクセス指定子を持つ using 宣言の実装分岐
次のプログラムは、C++ 標準に従って整形式ですか、それとも整形式ではありませんか?
コンパイラが異なれば、結果も異なります。Clang はそれを拒否し、GCC はそれを受け入れます。
- http://melpon.org/wandbox/permlink/SqSEtcYaR72A4eNS (クラン拒否)
- http://melpon.org/wandbox/permlink/N3ORCxG8qnU6Zmeq (GCC 承認)
http://eel.is/c++draft/class.paths#1によると、プログラムは整形式です(したがって、そのclangにはそれを拒否するバグがあります)と思いますが、よくわかりません:
複数の継承グラフを介して複数のパスで名前に到達できる場合、アクセスは、最も多くのアクセスを提供するパスのアクセスになります。
c++ - 宣言と引数に依存するルックアップを使用する C++
以下のコードは有効な C++98 ですか、それとも新しいバージョンの C++ 標準が必要ですか?
どうやら、私のコンパイラ (EDG フロント エンドに基づいていると思います) は、basic::f の using 宣言の後、user::f を考慮しません。C++98 によると、これは正しい動作ですか?