\n |
[ トップページ ]
[ ____CommandPrompt ]
[ ____JScript ]
[ ____MySQL ]
[ ____Cygwin ]
[ ____Java ]
[ ____Emacs ]
[ ____Make ]
[ ____Perl ]
[ ____Python ]
[ ____OpenGL ]
[ ____C# ]
[ ____StyleSheet ]
[ ____C++ ]
[ ____Winsock ]
[ ____Thread ]
[ ____VisualStudio ]
[ ____C ]
[ ____Win32API ]
[ ____Lua ]
[ ____PhotoShop ]
ヘッダ検索
■ コンパイラオプション(CompilerOption)
一覧を見るには cl.exe のヘルプを実行する。
■ Code.生成
POINT
リンカー渡されるすべてのモジュールは
同じランタイムライブラリ コンパイルオプション (/MD、/MT、/LD) を指定してコンパイルされている必要がある。
■ MT
マルチスレッド対応のスタティック バージョンのランタイム ライブラリが使用される。
POINT
コンパイラにライブラリ名 LIBCMT.lib を .obj ファイルに挿入させるため、
リンカーは LIBCMT.lib を使って外部シンボルを解決できる。
テキストエディタでコンパイル済みのオブジェクトを見ると、以下の記述があることがわかる。
■ MD
アプリケーションで
マルチスレッド対応バージョンおよび DLL 対応バージョンのランタイムライブラリが使用されます。
_MT および _DLL を定義し、
コンパイラにライブラリ名 MSVCRT.lib を .obj ファイルに挿入させます。
このオプションを使用してコンパイルされたアプリケーションは、
MSVCRT.lib に静的にリンクされます。
このライブラリは、リンカーが外部参照を解決できるようにするコードレイヤーを提供しています。
実際のコードは MSVCR100.DLL, に入っているので、
MSVCRT.lib とリンクされるアプリケーションの実行時には、
MSVCR80.DLL にアクセスできるようにしておく。
Cランタイムライブラリを DLL として利用する場合は /MD オプションでコンパイルする。
WARNING
/MD オプションでコンパイルしたオブジェクトをリンクすると manifest ファイルが生成される。
この manifest ファイルが DLL 本体の場所を示すため、実行ファイル(exe) と共に配布する必要がある。
main.cpp
main.obj
main.exe
main.exe.manifest
試しに manifest ファイルを削除してみる。
もし実行ファイルのみの環境で実行するとエラーが出る。
コンピュータに MSVCR90.dll がないため、プログラムを開始できません。
解決するには 実行ファイルと同じ場所に manifest ファイルを置く。
実際は manifest ファイルをいっしょに配布するのも手間なのでリソースとして実行ファイルに組み込む。
d:/tmp/main.exe
d:/tmp/main.exe.manifest
REFERENCE manifest
■ /Gm
DESC
簡易(最小)リビルド.変更部分のみを取得する
■ _DEBUG(NDEBUG)
DESC
"Debug" 構成で Default ON になっている
"Release" 構成では NDEBUG が有効。
POINT
アサートをリリース時に無効にするには NDEBUG を有効にする。
$vc/include/assert.h には次のようにある
#undef assert
// NDEBUG が ON ならば, assert は何もしない
// NDEBUG を OFF にすると assert にかかる
#ifdef NDEBUG
#else
#endif /* NDEBUG */
■ 言語設定
■ /Ze
VC++ の拡張を禁止する
使用可能にするには
/Ze
使用不能にするには
/Za
■ PreProcessor
POINT
PreProcessor への命令も含まれる
/I< dir> インクルード検索パスに追加
/C コメントを削除しない
/D< name>{=|#}< text> マクロを定義する
/E stdout に前処理する
/EP stdout に前処理する、#line なし
POINT
この手順なら
/EP, /P は不要
SolutionExplorer RMB xxx.cpp > Property
PreProcessor > 前処理済みファイルの生成 > 行番号つきか行番号なしを選択
// 生成
SolutionExplorer RMB xxx.cpp > Compile
■ /D
DESC
マクロ変数を定義する。
コード内で環境によって処理を切り替えるときに使う。
/D "WIN32" /D "TEST"
#ifdef WIN32
inclue < windows.h>
#else
#endif
■ #pragma(指令)
目的:
コンパイラに特定の情報を渡すため指令(pragma) するため
WARNING:
pragma はC++ 標準、
しかし書式、内容はコンパイラ依存により移植性なし
ANSI標準でない
POINT:
#pragma once 多重インクルード防止と同じ意味
主要なコンパイラ(VC、BC,gcc、CodeWarrior)では普通に
#pragma onceが使用できる
■ Warning
/we< n> 警告 n をエラーとして扱う
/wo< n> 警告 n を 1 度だけ表示する
/w< l>< n> n の警告レベル 1-4 を設定する
/W< n> 警告レベルを設定する (既定 n=1)
/Wall 警告をすべて有効にする
/WL 1 行診断を有効にする
■ WX
DESC
警告があった場合にエラー扱いにする。
これを指定するとすべての警告をなくさないと実行ファイルを生成することはできない。
POINT
STL には /W4 警告もあるため
特定の warning だけを無視するには /wd を使う。
ソースコード内にも設定できる。
// W3 に下げる
#pragma warning ( push, 3 )
#include< string>
// 戻す
#pragma warning ( pop )
// 無名の構造体です 警告を無効にする
#pragma warning ( disable : 4201 )
struct {
int i;
} p;
// 元に戻す
#pragma warning ( disable : 4201 )
■ /wd
DESC
指定した Warning を非表示( Disable )にする
■ その他
■ /nologo
DESC
Windows ... みたいな logo を消す。
■ /RTC
DESC
RunTimeCheck ( 実行時のエラーチェックをする )
u : 未初期化変数のチェック
s: スタックフレームのランタイム エラー チェックをする
スタック ポインタの検証によって、スタック ポインタの破損を検出する。
呼び出し規約の不一致によって、スタック ポインタが破損することがある。
たとえば、
関数のポインタを __cdecl として宣言したが、
関数ポインタを使用して __stdcall としてエクスポートされた DLL の関数を呼び出した場合。
23: int cnt;
24: printf( "ret %d\n", cnt );
0031108E cmp byte ptr [ebp-39h],0
00311092 jne main+91h (3110A1h)
00311094 push offset (311184h)
00311099 call _RTC_UninitUse (311A40h) // チェック用の関数がコールされる。
0031109E add esp,4
003110A1 mov esi,esp
003110A3 mov edx,dword ptr [ebp-28h]
003110A6 push edx
003110A7 push offset ___xi_z+12Ch (315744h)
003110AC call dword ptr [__imp__printf (3182C4h)]
■ EHsc
■ 最適化(Optimize)
/O1 スペースを最小化する
/O2 スペースを最大化する
/Ob< n> インライン展開 (既定値 n=0)
/Og グローバルな最適化を有効にする /Oi[-] 組み込み関数を有効にする
/Os コード スペースを優先する /Ot コードのスピードを優先する
/Ox 最大限の最適化
/Oy[-] フレーム ポインタの省略を有効にする
■ /Ox
DESC
/Ox 最大限の最適化
/Os コード スペースを優先する
■ /Ot
DESC
Code の Speed を優先
■ /Oi
DESC
組み込み関数を有効にする
コンパイラへ
一部の関数呼び出しを組み込み関数に置き換えるように要求する
コンパイラは
関数を呼び出した方が高いパフォーマンスが得られる場合は関数を呼び出すことがある
■ /Od
最適化をオフにする。
コンパイラはソースコードと同じようにアセンブラコードを生成する。
デバッグ時は余計な最適化をかけないように、/Od を指定する。
POINT
混合モードで見るとわかる。
15: int cnt = 0;
16: for( int i=0; i< 5; i++ ){
17: cnt ++;
18: }
19:
20: printf( "ret %d\n", cnt );
/O2 では cnt が push 5 としてコードが生成される。
002C1C3B push 5
002C1C3D push offset string "ret %d\n" (2C3950h)
002C1C42 call dword ptr [__imp__printf (2C622Ch)]
■ Debug用
■ C7
デバッグをするために利用するシンボルテーブルの形式を設定できる。
C7
MS-DOS 時代からのシンボルテーブルフォーマット
実行ファイルにシンボル情報が組み込まれるためファイルサイズは肥大化する。
WARNING
ファイルサイズが大きくなることと,
インクリメンタルリンクが無効になりリンク回数が増えるため利用しないほうがよい
PDB
PDB フォーマットは一般的に利用されているシンボルテーブルのフォーマット。
実行ファイルとは別の2つのファイルに出力される。
vc90.pdb : 型情報
test.pdb : シンボル情報
POINT
実行ファイルに pdb を含むかどうかは実行ファイル内にある文字列を調べればわかる。
"D:/vc/test/test.pdb" といったパスが埋め込まれている。
bash> strings test.exe | grep "test.pdb"
■ /Z7
DESC
obj file の中に Debug.情報 を組み込む( 古い形式 )
■ /Zi
DESC
デバッグ情報を生成
ProgramDataBase(pdb)を作成する
Debug.情報の形式
型情報は、.obj ではなく .pdb に配置される
/Zi を指定すると /debug が暗黙に指定される
( 内部的に指定したことになる )
POINT
Debug 情報の形式を指定する ( ON/OFF ではない )
Linker の設定もあわせて変更する
Obj file の Debug 情報を pdb file という別ファイルに保存する
POINT
Debug 情報とは 型情報 のこと
cl /Zi e.cpp
ls
// 生成されるもの
e.ilk
e.pdb
vc80.pdb
// まだ作成されない
nm e.exe
|
|
NINJAIDX 15