次のコードがあると想像してください
void A(){
// blah blah blah
}
void B(){
// blah blah blah
}
void C(){
// blah blah blah
}
コードを (Visual Studio を使用して) コンパイルし、メモリにロードして実行すると、A()、B()、C() のアドレスが順番どおりにならない場合があります。どうすれば注文できますか?この状況で役立つディレクティブはありますか?
次のコードがあると想像してください
void A(){
// blah blah blah
}
void B(){
// blah blah blah
}
void C(){
// blah blah blah
}
コードを (Visual Studio を使用して) コンパイルし、メモリにロードして実行すると、A()、B()、C() のアドレスが順番どおりにならない場合があります。どうすれば注文できますか?この状況で役立つディレクティブはありますか?
プログラムが単一の翻訳単位 (ソース ファイル) で構成されている場合、結果のバイナリには通常、翻訳単位で定義されている順序で関数が含まれている必要があります。たとえば、次のプログラムを考えてみましょう。
int A() { return 0; }
int B() { return 1; }
int C() { return -1; }
int main() { return A() + B() + C(); }
このプログラムを最小サイズ (/O1) に最適化し、インライン関数展開を無効にして (/Ob0) コンパイルすると、次のマシン コードが生成されます。
int A() { return 0; }
00F71000 33 C0 xor eax,eax
00F71002 C3 ret
int B() { return 1; }
00F71003 33 C0 xor eax,eax
00F71005 40 inc eax
00F71006 C3 ret
int C() { return -1; }
00F71007 83 C8 FF or eax,0FFFFFFFFh
00F7100A C3 ret
int main() { return A() + B() + C(); }
00F7100B E8 F0 FF FF FF call A (0F71000h)
00F71010 8B C8 mov ecx,eax
00F71012 E8 EC FF FF FF call B (0F71003h)
00F71017 03 C8 add ecx,eax
00F71019 E8 E9 FF FF FF call C (0F71007h)
00F7101E 03 C1 add eax,ecx
00F71020 C3 ret
ソース注釈は、デバッガーによって提供されます。最小サイズの最適化はint 3
、他の最適化設定が使用されている場合に関数間に配置されるパディングをなくすために必要です。結果のバイナリに関数が実際に存在することを確認するには、インライン関数展開を無効にする必要があります。
これは、私の知る限り、実装の詳細であるため、製品コードに依存するべきではありません。
読みやすくするためにそれらを個別の関数に分割し、プログラム全体で一度だけ呼び出す場合は、これらの関数をインラインで宣言すると、コンパイラは呼び出し命令なしでそれらを単一のコードに結合します。
それ以外の場合、呼び出し命令は CPU のパイプラインをフラッシュするため、それらをメモリに順番に配置する理由はありません。