Visual C++にまつわるよくある質問

Time-stamp: "2014-06-04 Wed 19:08 JST hig"

情報メディアセンターの管理する実習室の Windows にインストールされたVisual C++ 2008 を使って プログラミングをするときに出会うかもしれない問題です.

ビルドの際にscanfで警告が出る

この点でVisual C++のコンパイラはLinux のgccなどのコンパイラと振舞いが異なります. 無視してもいいですし,


#define _CRT_SECURE_NO_WARNINGS
して消すこともできます.

scanfは危険なので使わないほうがいいと考えられているというのは本当です.

プロジェクトを作ろうとすると「フォルダ(何とか)に既に別のプロジェクトが存在するため, プロジェクトを作成できません」と言われる

その通りです. エクスプローラでそのフォルダを消去する(不要なら)か, 別のプロジェクト名を選ぶかしましょう.

ソリューションエクスプローラ上にプロジェクトが表示されないとしても, Visual Studioにプロジェクトとして登録されていないだけで, フォルダの実体は存在することがあります. 完全に削除するには, Visual Studio上でプロジェクトを削除するだけでなく, エクスプローラでフォルダを削除する必要があります.

新しい項目の追加でファイルを追加しようとするのにできない

そのウィンドウ, 似てるけどクラスビューじゃありませんか? 新しい項目の追加をするのは, ソリューションエクスプローラというウィンドウです. ソリューションエクスプローラが表示されていない場合, メニューから表示>ソリューションエクスプローラを選びます. IDEの使い方に前後を含めて説明しています.

新しい項目の追加でファイルを追加しようとすると「(何とか)という名前のファイルはディスクに既に存在します」と言われる

その通りです. エクスプローラでそのファイルを消去する(不要なら)か, 別のファイル名を選ぶかしましょう.

ソリューションエクスプローラのプロジェクト内にファイルが表示されないとしても, Visual Studioに登録されていないだけで, ファイルの実体は存在することがあります. 完全に削除するには, Visual Studio上でファイルををクリアするだけでなく, 削除しましょう. またはエクスプローラでファイルを削除する必要があります.

気合いをいれてプログラムをいろいろ変更しているのに, 実行したときの振る舞いが全然変化しない

意図したのと別のファイルを編集していませんか? タブ上に出るファイル名が同じでも別のフォルダ内のものかも. ソリューションエクスプローラから開き直してみましょう.

意図したのと別のプログラムを実行していませんか? 「デバッグ開始」「デバッグなしで開始」で実行されるプログラムは, ソリューションエクスプローラ上で太字で表示されている「スタートアッププロジェクト」です. 設定はプロジェクト>スタートアッププロジェクトの設定で行います.

`プロジェクトを開く'を選んでも`開けない'

これは, ソリューションエクスプローラが消えている状態だという ことでしょうか. ソリューションエクスプローラを表示するには, 表示 > ソリューションエクスプローラ です.

ビルドの際に `M_PI': 定義されていない識別子です, と言われる

Linux のCでは math.h を include すると, M_PI などの数学定数のマクロが使えました. しかし, これは ANSI C の標準の機能ではなく, サービス機能です. Visual Studio .NET で M_PI などの数学定数のマクロを使うには, math.hをinclude する前に, _USE_MATH_DEFINES を define しなければなりません.

#define _USE_MATH_DEFINES
#include <math.h>

なお, コマンドライン, IDEとも, Linuxのコマンドラインででcc-lmオプションを与える, に相当することは不要です.

ビルドの際に `_main はすでに (何とか).obj で定義されています' と言われる

1個のプロジェクトの中に, main 関数を含む *.cファイルを2個以上入れていませんか? 1個のプロジェクトに実行ファイルは1個, したがって, main 関数は1個だけです. 2個のプログラム(実行ファイル)を作りたいときは, 2個のソリューション/2個のプロジェクトを作りましょう.

この授業では, 1個のソリューションに1個のプロジェクト, 1個のプロジェクトに1個の .c ファイル(ヘッダーファイルは無し)という使い方をします.

ビルドの際に`構文エラー: `;'が`識別子'の前にありません'と言われる

言葉通り,

    printf("Hello world!\n")
のように, 行末の(つまり次の行の最初の単語の前に)セミコロン;が足りないというエラーです.

また, 一見 セミコロン; が不要と思われる場所でこのエラーが発生することがあります. それは, {} が match していないためであることがあります. 次の例で考えてみましょう.

int main(int argc, char **argv){

    return do_hello_world();

/* } */                  /* } 付け忘れ */

int do_hello_world(void){
    printf("Hello world!\n");
    return 0;
}
C++コンパイラは, int do_hello_world(void){ も main 関数の中にあると解釈することになります. ところが, 関数の中で関数を定義することはできません. そこで C++ コンパイラーは,
int do_hello_world; /* ; を補いました */

(void){
...
} /* 
と, 変数の宣言と解釈し, do_hello_world の後に セミコロン; がないよ, と文句を言うのです. C++ では(Cと異なり, またJavaと同じ様に)関数定義の先頭でなく, 任意の場所で変数の宣言が可能なのでした.

ビルドの際に`文字 `0x81' は認識できません' と言われる

ソースに全角スペースが含まれています. 半角スペースに直しましょう.

ビルドの際に `ファイル (何とか).exe を削除できませんでした' と言われる

これは, 実行中のプログラムを(終了しないまま)再度ビルドしようとした場合でしょうか. ビルドする前に, プログラム(開始で生じるウィンドウ)を終了しておきましょう.

ビルドの際に `LINK: 書き込みモードで …\Debug/(何とか).exe を開けません' と言われる

これは, 実行中のプログラムを(終了しないまま)再度ビルドしようとした場合でしょうか. ビルドする前に, プログラム(開始で生じるウィンドウ)を終了しておきましょう.

ビルドの際に `error LNK2019:未解決の外部シンボル WinMain@16が関数 WinMainCRTStartupで参照されました。fatal error LNK1120:外部参照1が未解決です。'などと言われる

空のWin32コンソールプロジェクトとして作られてない のでしょう(たぶん, 空のWin32プロジェクトなのでは?). ソースファイルはとっておいて, Win32コンソールプロジェクトとして作り直して, 既存項目の追加でソースファイルを戻せばいいのでは.

ビルドの際に `LINK1201: プログラムデータベース …\Debug\(何とか).pdbに書き込めません, と言われる

何らかの原因で, 異常な状態で, ファイル (何とか).pdb が残ってしまったようです. 手で(エクスプローラで)このファイルを削除するか, Visual Studio を再起動するかしてみましょう.

実行の際に `Line: 39. The variable 'n' is being used without being defined.'というダイアログがでて実行できない

variable=変数, define=定義する(今の場合, 初期化のことです). Line=行. 39行目あたりをチェックしましょう.

Unix/Linuxのcc/gccや, Visual C++のRelease Buildでは, 《実行できちゃうけどおかしな結果になる》ケースです. デバッガーで実行したときにはこうして警告してくれるのです.

実行の際に `Real-Time Check Failure #3 - The variable 'n' is being used without being initialized.'というダイアログがでて実行できない

variable=変数, initialize=初期化する. チェックしましょう.

Unix/Linuxのcc/gccや, Visual C++のRelease Buildでは, 《実行できちゃうけどおかしな結果になる》ケースです. デバッガーで実行したときにはこうして警告してくれるのです.

デバッグの際に `Run-Time Check Failure #2 - Stack around the variable 'x' was corrupted.' などというダイアログがでる

Stack というのは関数内で一時的に確保される変数領域のことです. それが壊れたというのですから, Segmentation Fault と似た状況です

典型的には, x という配列を, 許される添字範囲を超えて使ってしまったときなどに起きます.


Copyright © 2003-2014 Saburo Higuchi. All rights reserved.
樋口三郎 http://www.math.ryukoku.ac.jp/~hig/