次のプログラムを検討してください。
_#include <iostream>
int main = ( std::cout << "C++ is excellent!\n", 195 );
_
Windows 7 OSでg ++ 4.8.1(mingw64)を使用すると、プログラムはコンパイルして正常に実行され、印刷されます。
C++は素晴らしい!
コンソールに。 main
は、関数ではなくグローバル変数のようです。このプログラムは、関数main()
なしでどのように実行できますか?このコードはC++標準に準拠していますか?プログラムの動作は明確に定義されていますか? _-pedantic-errors
_オプションも使用しましたが、プログラムは引き続きコンパイルおよび実行されます。
3.6.1/1から:
プログラムには、プログラムの指定された開始であるmainと呼ばれるグローバル関数が含まれます。独立した環境のプログラムがメイン機能を定義するために必要かどうかは、実装によって定義されます。
このことから、g ++は、メイン関数なしで(おそらく「自立」節として)プログラムを許可するように見えます。
その後、3.6.1/3から:
関数mainはプログラム内で使用されません(3.2)。 mainのリンケージ(3.5)は実装定義です。 mainがインラインまたは静的であることを宣言するプログラムは不正です。それ以外の場合、メイン名は予約されていません。
したがって、ここでは、main
という名前の整数変数を持つことはまったく問題ないことを学びます。
最後に、出力が出力される理由を知りたい場合は、int main
は、コンマ演算子を使用して静的初期化でcout
を実行し、初期化を行うために実際の整数値を提供します。
gcc 4.8.1は、次のx86アセンブリを生成します。
.LC0:
.string "C++ is excellent!\n"
subq $8, %rsp #,
movl std::__ioinit, %edi #,
call std::ios_base::Init::Init() #
movl $__dso_handle, %edx #,
movl std::__ioinit, %esi #,
movl std::ios_base::Init::~Init(), %edi #,
call __cxa_atexit #
movl $.LC0, %esi #,
movl std::cout, %edi #,
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) #
movl $195, main(%rip) #, main
addq $8, %rsp #,
ret
main:
.zero 4
cout
は、main
関数ではなく、初期化中に呼び出されることに注意してください!
.zero 4
は、main
から始まる4(0で初期化された)バイトを宣言します。ここで、main
はvariable [!]の名前です。
main
シンボルは、プログラムの開始として解釈されます。動作はプラットフォームによって異なります。
それは不正なプログラムです。テスト環境cygwin64/g ++ 4.9.3でクラッシュします。
標準から:
.6.1メイン関数 [basic.start.main]
1プログラムには、プログラムの指定された開始であるmainというグローバル関数が含まれます。
私がこれがうまくいくと思う理由は、compilerがmain()
関数をコンパイルしていることを知らないので、グローバル整数をコンパイルします割り当ての副作用。
このtranslation-unitがコンパイルされるobject formatは使用できません関数シンボルと変数シンボルの区別.
linkerは、(変数)mainシンボルにリンクし、処理します関数呼び出しのようです。しかし、runtime systemがグローバル変数初期化コードを実行するまではそうではありません。
サンプルを実行すると印刷されましたが、seg-faultが発生しました。 ランタイムシステムがint変数を実行しようとしたときだと思います関数の場合。
VS2013を使用してWin7 64ビットOSでこれを試しましたが、正しくコンパイルされますが、アプリケーションをビルドしようとすると、出力ウィンドウからこのメッセージが表示されます。
1>------ Build started: Project: tempTest, Configuration: Debug Win32 ------
1>LINK : fatal error LNK1561: entry point must be defined
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========