"Hello, World!"レベルの単純なプログラムを題材に、基本的なコンパイルオプションのまとめ。
対象:Visual C++ 2008 Express Edition
> cl Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. > link Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved.
ここではコンソール/GUI/DLLに関わらず共通して使われそうなオプションをまとめてみた。
シンプルな基本:
HelloWorld.c:
#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
コンパイル:
> cl HelloWorld.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. HelloWorld.c Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:HelloWorld.exe HelloWorld.obj
実行:
> HelloWorld.exe Hello, World!
HelloWorld.c:
#include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, World!\n"); return 0; }
コンパイル:"/Wall"
> cl /Od /nologo /Wall HelloWorld.c
HelloWorld.c
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\stdio.h(381) : \
warning C4255: '_get_printf_count_output' : 関数プロトタイプがありません \
: '()' を '(void)' に変換します。
HelloWorld.c(3) : warning C4100: 'argv' : 引数は関数の本体部で 1 度も参照されません。
HelloWorld.c(3) : warning C4100: 'argc' : 引数は関数の本体部で 1 度も参照されません。
コンパイル:"/W3"
> cl /Od /nologo /W3 HelloWorld.c HelloWorld.c
main.c:
#include <stdio.h>
extern int foo(int a, int b, int c, int d);
extern int bar(int a, int b, int c, int d);
int main(int argc, char *argv[])
{
int r;
r = foo(4, 3, 2, 1);
printf("foo() = %d\n", r);
r = bar(4, 3, 2, 1);
printf("bar() = %d\n", r);
return 0;
}
foo.c:
int foo(int a, int b, int c, int d)
{
int r;
r = a + b + c + d;
return r;
}
bar.c:
int bar(int a, int b, int c, int d)
{
int r;
r = a - b - c - d;
return r;
}
分割コンパイル:
> cl /c foo.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. foo.c > cl /c bar.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. bar.c > cl /c main.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. main.c
手動でリンク:先頭に指定した".obj"ファイル名で".exe"が生成される。
> link main.obj foo.obj bar.obj Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. > main.exe foo() = 10 bar() = -2
foo.objを先頭に指定すると、"foo.exe"が生成される。
> link foo.obj main.obj bar.obj Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. > foo.exe foo() = 10 bar() = -2
"/OUT:filename"でファイル名を指定出来る。
> link /OUT:foobarmain.exe main.obj foo.obj bar.obj Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. > foobarmain.exe foo() = 10 bar() = -2
デフォルトでは拡張子から自動判別する。次のオプションを指定することで、明示的に入力ソースファイルの言語が"C"か"C++"かを指定出来る。
"/TC"のテスト版:HelloWorld_TCtest.foo:
#include <stdio.h>
/* C style multi line comment */
// C++ style single line comment
int main(int argc, char *argv[]) {
printf("Hello, World!\n");
return 0;
}
コンパイル&実行:
> cl /TC HelloWorld_TCtest.foo Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. HelloWorld_TCtest.foo Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:HelloWorld_TCtest.exe HelloWorld_TCtest.obj > HelloWorld_TCtest.exe Hello, World!
"/TP"のテスト版:HelloWorld_TPtest.foo:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, World!" << endl;
return 0;
}
コンパイル&実行:
> cl /TP HelloWorld_TPtest.foo
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
HelloWorld_TPtest.foo
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xlocale(342) : warning C4530: \
C++ 例外処理を使っていますが、アンワインド セマンティクスは有効にはなりません。\
/EHsc を指定してください。
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:HelloWorld_TPtest.exe
HelloWorld_TPtest.obj
> HelloWorld_TPtest.exe
Hello, World!
"/EHsc"指定を行うと上記警告は消える:
> cl /TP /EHsc HelloWorld_TPtest.foo Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. HelloWorld_TPtest.foo Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:HelloWorld_TPtest.exe HelloWorld_TPtest.obj
VC++2008のC/C++コンパイラでは、デフォルトではMicrosoftによるC/C++言語拡張機能が有効化されている。
これにより、C言語としてコンパイルする場合でもC++形式の一行コメント、"//"が使えるようになっている。
一行コメントの場合、エスケープシーケンスが行末にあると次の行もコメントとして認識するようになっている。ただし、実際に使ってみると、以下の警告が表示される。
warning C4010: 単一行コメント (//) に、行連結文字があります。
また、"/Ze"の明示的な指定は現在推奨されていないらしい。下記に示すように今後のバージョンからは削除される旨の警告が表示される。
コメントスタイル検証用:HelloWorld_TCtest.foo:
#include <stdio.h>
/* C style multi line comment */
// C++ style single line comment
int main(int argc, char *argv[]) {
printf("Hello, World!\n");
return 0;
}
"/Ze"でコンパイル:
> cl /Ze /TC HelloWorld_TCtest.foo
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
cl : コマンド ライン warning D9035 : オプション 'Ze' の使用は現在推奨されていません。\
今後のバージョンからは削除されます。
HelloWorld_TCtest.foo
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:HelloWorld_TCtest.exe
HelloWorld_TCtest.obj
"/Za"でコンパイル:
> cl /Za /TC /W3 HelloWorld_TCtest.foo Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. HelloWorld_TCtest.foo Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:HelloWorld_TCtest.exe HelloWorld_TCtest.obj
"/Za"でも、"/W3"までの警告指定では単一行コメントについては警告もエラーも表示されなかった。
"/W4"まで警告レベルを上げることで、警告が表示されるようになる。
> cl /Za /TC /W4 HelloWorld_TCtest.foo
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
HelloWorld_TCtest.foo
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\sal.h(108) : \
warning C4001: 標準外の言語拡張 (単一行コメント) が行われています。
HelloWorld_TCtest.foo(6) : warning C4100: 'argv' : 引数は関数の本体部で 1 度も参照されません。
HelloWorld_TCtest.foo(6) : warning C4100: 'argc' : 引数は関数の本体部で 1 度も参照されません。
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:HelloWorld_TCtest.exe
HelloWorld_TCtest.obj
実験用のファイル構成:
pptest.c
inc/
pptest.h
pptest.c:
#include "pptest.h"
/**
* comment1
*/
int foo(int a, int b) {
return a + b;
}
/**
* comment2
*/
int bar(int a, int b) {
return a * b;
}
pptest.h:
#ifdef _DEBUG char message[] = "Debug Message"; #else char message[] = "Release Message"; #endif /* _DEBUG */
実験1:"/I"を指定しない→コンパイルエラー(fatal error C1083)
> cl /c pptest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. pptest.c pptest.c(1) : fatal error C1083: include ファイルを開けません。'pptest.h': No such file or directory
実験2:"/I"を指定→コンパイル成功
> cl /c /I .\inc pptest.c
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
pptest.c
> dir pptest.obj
(...)
2010/02/11 11:46 625 pptest.obj
1 個のファイル 625 バイト
(...)
実験3:pptest.cでstdio.hをインクルードさせた上で、"/X"で標準インクルードディレクトリを無視させる→コンパイルエラー(fatal error C1083)
> cl /c /X /I .\inc pptest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. pptest.c pptest.c(1) : fatal error C1083: include ファイルを開けません。'stdio.h': No such file or directory
「インクルードパスの調整」で使ったpptest.c, pptest.hを使って実験してみる。
※見やすくする為、プリプロセス結果中の連続する空行は一行に縮めています。
> cl /E /I .\inc pptest.c
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
pptest.c
#line 1 "pptest.c"
#line 1 ".\\inc\\pptest.h"
char message[] = "Release Message";
#line 6 ".\\inc\\pptest.h"
#line 2 "pptest.c"
int foo(int a, int b) {
return a + b;
}
int bar(int a, int b) {
return a * b;
}
> cl /EP /C /I .\inc pptest.c
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
pptest.c
char message[] = "Release Message";
/**
* comment1
*/
int foo(int a, int b) {
return a + b;
}
/**
* comment2
*/
int bar(int a, int b) {
return a * b;
}
> cl /D _DEBUG /P /C /I .\inc pptest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. pptest.c
保存されたファイル内容:pptest.i:
#line 1 "pptest.c"
#line 1 ".\\inc\\pptest.h"
char message[] = "Debug Message";
#line 6 ".\\inc\\pptest.h"
#line 2 "pptest.c"
/**
* comment1
*/
int foo(int a, int b) {
return a + b;
}
/**
* comment2
*/
int bar(int a, int b) {
return a * b;
}
> cl /D _DEBUG /P /EP /C /I .\inc pptest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. pptest.c
保存されたファイル内容:pptest.i:
char message[] = "Debug Message";
/**
* comment1
*/
int foo(int a, int b) {
return a + b;
}
/**
* comment2
*/
int bar(int a, int b) {
return a * b;
}
※いずれのオプションでもコンパイル以降の処理も続行される。
実験ファイル:fatest.c:
int foo(int a, int b, int c)
{
int r;
r = a + b + c;
r *= 3;
return r;
}
> cl /c /Od /FA fatest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. fatest.c
fatest.asm:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 TITLE C:\in_vitro\c\cltest02\fatest.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES PUBLIC _foo ; Function compile flags: /Odtp _TEXT SEGMENT _r$ = -4 ; size = 4 _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 _foo PROC ; File c:\in_vitro\c\cltest02\fatest.c ; Line 2 push ebp mov ebp, esp push ecx ; Line 4 mov eax, DWORD PTR _a$[ebp] add eax, DWORD PTR _b$[ebp] add eax, DWORD PTR _c$[ebp] mov DWORD PTR _r$[ebp], eax ; Line 5 mov ecx, DWORD PTR _r$[ebp] imul ecx, 3 mov DWORD PTR _r$[ebp], ecx ; Line 6 mov eax, DWORD PTR _r$[ebp] ; Line 7 mov esp, ebp pop ebp ret 0 _foo ENDP _TEXT ENDS END
> cl /c /Od /FAc fatest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. fatest.c
fatest.cod:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 TITLE C:\in_vitro\c\cltest02\fatest.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES PUBLIC _foo ; Function compile flags: /Odtp _TEXT SEGMENT _r$ = -4 ; size = 4 _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 _foo PROC ; File c:\in_vitro\c\cltest02\fatest.c ; Line 2 00000 55 push ebp 00001 8b ec mov ebp, esp 00003 51 push ecx ; Line 4 00004 8b 45 08 mov eax, DWORD PTR _a$[ebp] 00007 03 45 0c add eax, DWORD PTR _b$[ebp] 0000a 03 45 10 add eax, DWORD PTR _c$[ebp] 0000d 89 45 fc mov DWORD PTR _r$[ebp], eax ; Line 5 00010 8b 4d fc mov ecx, DWORD PTR _r$[ebp] 00013 6b c9 03 imul ecx, 3 00016 89 4d fc mov DWORD PTR _r$[ebp], ecx ; Line 6 00019 8b 45 fc mov eax, DWORD PTR _r$[ebp] ; Line 7 0001c 8b e5 mov esp, ebp 0001e 5d pop ebp 0001f c3 ret 0 _foo ENDP _TEXT ENDS END
> cl /c /Od /FAs fatest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. fatest.c
fatest.asm:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
TITLE C:\in_vitro\c\cltest02\fatest.c
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC _foo
; Function compile flags: /Odtp
; File c:\in_vitro\c\cltest02\fatest.c
_TEXT SEGMENT
_r$ = -4 ; size = 4
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_c$ = 16 ; size = 4
_foo PROC
; 2 : {
push ebp
mov ebp, esp
push ecx
; 3 : int r;
; 4 : r = a + b + c;
mov eax, DWORD PTR _a$[ebp]
add eax, DWORD PTR _b$[ebp]
add eax, DWORD PTR _c$[ebp]
mov DWORD PTR _r$[ebp], eax
; 5 : r *= 3;
mov ecx, DWORD PTR _r$[ebp]
imul ecx, 3
mov DWORD PTR _r$[ebp], ecx
; 6 : return r;
mov eax, DWORD PTR _r$[ebp]
; 7 : }
mov esp, ebp
pop ebp
ret 0
_foo ENDP
_TEXT ENDS
END
> cl /c /Od /FAsc fatest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. fatest.c
fatest.cod:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
TITLE C:\in_vitro\c\cltest02\fatest.c
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC _foo
; Function compile flags: /Odtp
; File c:\in_vitro\c\cltest02\fatest.c
_TEXT SEGMENT
_r$ = -4 ; size = 4
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_c$ = 16 ; size = 4
_foo PROC
; 2 : {
00000 55 push ebp
00001 8b ec mov ebp, esp
00003 51 push ecx
; 3 : int r;
; 4 : r = a + b + c;
00004 8b 45 08 mov eax, DWORD PTR _a$[ebp]
00007 03 45 0c add eax, DWORD PTR _b$[ebp]
0000a 03 45 10 add eax, DWORD PTR _c$[ebp]
0000d 89 45 fc mov DWORD PTR _r$[ebp], eax
; 5 : r *= 3;
00010 8b 4d fc mov ecx, DWORD PTR _r$[ebp]
00013 6b c9 03 imul ecx, 3
00016 89 4d fc mov DWORD PTR _r$[ebp], ecx
; 6 : return r;
00019 8b 45 fc mov eax, DWORD PTR _r$[ebp]
; 7 : }
0001c 8b e5 mov esp, ebp
0001e 5d pop ebp
0001f c3 ret 0
_foo ENDP
_TEXT ENDS
END