[解決済み] int main;' は有効なC/C++プログラムですか?
質問
私はそう思っていないのですが、私のコンパイラはそう思っているようなので質問します。
echo 'int main;' | cc -x c - -Wall
echo 'int main;' | c++ -x c++ - -Wall
Clang はこれに対して警告もエラーも出さず、gcc は簡単な警告を出すだけです。
'main' is usually a function [-Wmain]
ただし、C言語としてコンパイルされた場合のみです。
-std=
を指定することは重要でないようです。
それ以外は、コンパイルもリンクもうまくいきます。しかし、実行時にはすぐに
SIGBUS
で終了してしまいます(私の場合)。
の(素晴らしい)回答に目を通すと
CおよびC++でmain()は何を返すべきですか?
での (素晴らしい) 回答と、言語仕様書をざっと読んでみると、確かに
と思われます。
がメインであることは間違いないでしょう。
機能
が必要です。しかし、gccの文言は
-Wmain
('main' は
通常
関数)(そして、ここでのエラーの少なさ)は、おそらくそうでないことを示唆しているようです。
しかし、なぜでしょうか?これには何か奇妙なエッジケースまたは「歴史的」な使い方があるのでしょうか。どなたか、何が原因かご存知ですか?
私が言いたいのは、私が本当にこれを エラー であるべきだということです。
どのように解決するのですか?
質問がCとC++のダブルタグになっているため、C++とCでは理由が異なるでしょう。
-
C++ では、リンカーが異なるタイプのテキスト的に同一のシンボル (たとえばグローバル変数) を区別できるようにするため、名前のマングリングを使用します。
xyz
と独立したグローバル関数xyz(int)
. しかし、名前main
は決して揶揄されることはありません。 - C ではマングリングを使用しないため、ある種のシンボルを別のシンボルの代わりに提供することによってリンカーを混乱させ、プログラムを正常にリンクさせることが可能です。
これがここで起こっていることです。リンカはシンボル
main
というシンボルが見つかるとリンカーは期待し、実際に見つかりました。リンカはそのシンボルをあたかも関数であるかのように配線しています。ランタイムライブラリのうち、制御を
main
をリンカに要求します。
main
を要求しているので、リンカはそれにシンボル
main
を与え、リンクフェーズを完了させます。もちろん、これは実行時に失敗します。
main
は関数ではないためです。
同じ問題の別の図解を示します。
ファイルx.c:
#include <stdio.h>
int foo(); // <<== main() expects this
int main(){
printf("%p\n", (void*)&foo);
return 0;
}
ファイルy.c:
int foo; // <<== external definition supplies a symbol of a wrong kind
をコンパイルします。
gcc x.c y.c
これはコンパイルされ、おそらく実行されるでしょうが、コンパイラに約束されたシンボルの型がリンカに供給された実際のシンボルと異なるため、未定義の動作となります。
警告に関しては、私は合理的だと思います。C 言語では
main
関数を持たないライブラリを構築できるため、コンパイラは
main
を他の用途に使うことができます。
main
を定義する必要がある場合です。
関連
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む
-
[解決済み] C++でintをstringに変換する最も簡単な方法
-
[解決済み] Could not find or load main class "とはどういう意味ですか?
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] CとC++でmain()は何を返すべきですか?
-
[解決済み] なぜ (int)x ではなく static_cast<int>(x) を使うのですか?
-
[解決済み] C言語とC++の両方で有効なコードを、それぞれの言語でコンパイルすると、異なる動作になることがありますか?
-
[解決済み] なぜJavaのmainメソッドは静的なのですか?
-
[解決済み】「int main(){([](){})();}」はどのように有効なC++なのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】'cout'は型名ではない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み] CとC++でmain()は何を返すべきですか?