Borland C++ Compiler 5.5 - FAQ

By: Hitoshi Fujii

Abstract: Borland C++ Complierに関する一般的な質問と回答を掲載します。この記事は、www.borland.co.jpに掲載されていた内容を転載したものです。

    基本機能に関する一般的な質問と回答

    Q. コマンドラインコンパイラとは何でしょうか。C++BuilderやVisual C++などのC++開発ツールとは、何が違うのでしょうか。

A. C++BuilderやVisual C++では、[スタート]メニューに登録されているメニュー項目を選んだり、デスクトップに表示されているアイコンを使って起動し、編集・コンパイル・デバッグなどの作業を統合した「開発環境」を使います。これに対して、BCC55は、コマンドラインツールと呼ばれる機能のみを提供しています。

コマンドラインとは、Windows 9xの[スタート]メニューから[プログラム]→[MS-DOS]プロンプト(NT 4.0では[コマンドプロンプト]、Windows 2000では[アクセサリ]→[コマンドプロンプト])で呼び出されるコンソール画面で、1行ずつ命令を入力する場所です。ここには、通常C:\Windows>」のようにカレントディレクトリと「>」という記号が表示されています(Fig.1参照)。

Fig.1 Windows 98のMS-DOSプロンプト
Hide image

BCC55は、C/C++のソースコード(.c、.cppなど)から実行ファイル(.exeなど)を作成するためのコンパイラやリンカは含まれていますが、エディタやデバッガはありません。

このため、BCC55でコンパイルするソースコードを記述するには、他のツール(テキストエディタ)が必要になります。Windowsに付属するメモ帳(Notepad.exe)やコンソール画面用のエディタ(Edit.exe)でもかまいませんが、他のエディタを用意するとよいでしょう。

    Q. プログラムは、どんな書き方をすればよいのでしょうか。また、どのようにして実行ファイルにすればよいでしょうか。

A. BCC55は、ANSI C++およびANSI Cに準拠したC/C++コンパイラです。特定の開発ツールではなく、CやC++言語を解説した市販の書籍が参考になります(注)。

プログラムは、テキストファイルとして記述し、拡張子が.cや.cppというファイルに保存します。List 1は、典型的なC++プログラムの例です。

List 1 ソースコードの例(hello.cpp)

#include <iostream.h>
main()
{
    cout << "Hello, World!" << endl;
    return 0;
}

このプログラムを実行ファイルにする場合は、コマンドラインで次のように入力します。

C:\WORK>bcc32 hello.cpp

注:市販の書籍の中には、ANSI C++の最新でない仕様をもとに記載されているものもあります。詳しくは、各出版社にお問い合わせください。

    Q. BCC55は、どんな形式の実行ファイルを作成できるのでしょうか。

A. BCC55では、Windows 95/98/NT/2000対応の32ビットアプリケーションが作成できます。これには、通常のGUIアプリケーション(.EXE)の他に、コンソールアプリケーションやダイナミックリンクライブラリ(.DLL)が含まれます。それぞれのターゲットに対応するコマンドラインオプションをTable 1に示します。

Table 1 コマンドラインオプション

ターゲット

オプション

GUIアプリケーション

-W(*1)

コンソールアプリケーション

-WC(*1)

ダイナミックリンクライブラリ

-WD(*1)

マルチスレッドファイル

-WM(*2)

Unicodeアプリケーション

-WU(*2)

ダイナミックRTLを使用

-WR(*2)

*1 いずれかひとつだけが有効です。
*2 他のオプションと組み合わせて使用します。

コマンドラインオプション-W?は、-tW?という指定と同じです。これは、Borland C++の16ビット版でDOSアプリケーションを作成する際に-tD?というオプションが存在していた頃の名残です。

    Q. C++BuilderやVisual C++で作成するようなグラフィカルユーザーインターフェース(GUI)を持つアプリケーションは、どのように開発すればよいのでしょうか。

A. BCC55でANSI C/C++準拠のアプリケーションを作成する場合、通常はコンソールアプリケーションになります。これは、BCC55自身と同じように、DOS(コマンド)プロンプトで実行させるものです。作成したプログラムをエクスプローラから実行させる場合は、自動的にコンソール画面が表示されます。

これに対して、C++BuilderやVisual C++などの市販の開発ツールは、VCLやMFCといったクラスライブラリを使ってGUIアプリケーションの構築を容易にしています。BCC55には、GUI用のクラスライブラリは提供されていないため、Windows APIを利用してアプリケーションを作成する必要があります。たとえば、アプリケーションのエントリ関数は、mainではなくWinMainになり、ウィンドウクラスの登録やウィンドウプロシージャ、メッセージループなどを、すべてプログラミングする必要があります。

APIを利用したWindowsプログラミングについては、『プログラミング Windows 95』(Charles Petzold著、アスキー)などを参考にしてください。

    Q. リソースファイルを作成するには、どうすればよいでしょうか。

A. Windows APIベースのGUIアプリケーションを開発する際には、通常、メニューやダイアログボックス、アイコンなどをリソースとして実行ファイルにバインドします。

BCC55には、グラフィカルなリソースエディタは含まれていません。このため、リソーススクリプト(.RC)を記述して、リソースコンパイラ(BRC32/BRCC32)でコンパイルしたり、リンカで実行ファイルにバインドしなければなりません。リソーススクリプトの形式については、『プログラミング Windows 95』などの資料を参照してください。また、各種の開発ツールが提供するリソースエディタで作成するリソースファイルも利用できます。

Borland C++ 2005 Suite にはスタンドアロンのリソースエディタ(Resource Workshop 4.5J)が含まれています。Resource Workshop 4.5Jは16ビットで動作し、16/32ビットのリソースを編集可能です(長いファイル名などには対応していません)。

    Q. BCC55で作成したプログラムをデバッグするにはどうすればよいでしょうか。

A. BCC55には、デバッグツールは含まれていません。Borland C++ Suiteに含まれているTurbo Assembler 5.0J には、BCC55で作成したアプリケーションをデバッグできる Turbo Debugger for Win32 というツールが含まれています。

Turbo Debugger for Win32をお持ちの方は、コンパイル時にコマンドラインオプションとして-vを指定することで、Turbo Debugger用のデバッグ情報ファイル(.TDS)を生成できます。

    Q. コンソールアプリケーションのままグラフィックスを使うことはできますか。以前、Turbo C++でBGI(Borland Graphics Interface)を使ったことがあります。

A. BCC55では、BGIのようにコンソール画面にグラフィックスを描画することはできません。Windowsでは、グラフィックスを利用するためにはウィンドウを作成しなければなりません。同様に、BIOSを直接呼び出すこともできません。

なお、コンソール入出力関数(conio)はサポートされているため、表示位置や色などを指定することはできます。

List 2 コンソール関数の利用例

#include <conio.h>

main(int argc, char **argv)
{
    enum COLORS c = WHITE;
    while (--argc) {
        textcolor(--c);
        cprintf("Hello, %s\r\n",
            *++argv);
    }
    return 0;
}

Fig 2 List 2の実行例

Hide image

    Q. インラインアセンブリ(ソースコード内でアセンブリ言語を使うこと)はサポートされていますか。

A. BCC32には、インラインアセンブリに必要なコマンドラインアセンブラが含まれていません。Borland C++ Suite に含まれる Turbo Assembler 5.0J などのコマンドラインアセンブラがあれば、asm(または_asm、__asm)文を使ってインラインアセンブリを記述できます。

List 3 インラインアセンブリの使用例

#pragma inline
unsigned reverse(unsigned value)
{
    asm {
        mov edx, [value]
        mov ecx, 32
iter:; shr edx, 1
        rcl eax, 1
        loop iter
    }
    return _EAX;
}

    付属ツールに関する一般的な質問と回答

    Q. BCC55には、コンパイラ(BCC32)やリンカ(ILINK32)、リソースコンパイラ(BRC32/BRCC32)以外に、どんなツールが含まれていますか。

A. BCC55には、Windowsアプリケーションを作成するだけでなく、外部のインポートライブラリを利用したり、プログラム自身の解析に役立つツールが含まれています。これらも、コンパイラやリンカと同じように、コマンドラインで利用します。以下に、各ツールについて解説します。

●COFF2OMF

マイクロソフト社のC++向けに開発されたライブラリをインプライズ製のC++で使えるように変換するためのものです。COFF(Common Object File Format)とは、マイクロソフト製のC++開発ツールなどで使われているライブラリの形式です。これに対して、インプライズ製のC++開発ツールではOMF(Object Module Format)という形式が使われています。COFF2OMFでサポートされるのは、ダイナミックリンクライブラリ(DLL)に対応するインポートライブラリのみです。スタティックライブラリを変換しても、暗黙のうちに使われるヘルパ関数やその他の問題があるため、正しくリンクできません。さらに、C++として宣言された外部シンボル・クラスなどは名前の変換形式が異なるため使えません。

●CPP32

BCC32が行うコンパイル処理のうちC/C++としてのプリプロセッサの処理だけを行います。プリプロセッサとは、ソースコード中に#で始まる指令(#includeや#define)などを処理する機能です。通常のC/C++コンパイラでは、プリプロセッサは実際の構文解析に先だって処理されますが、BCC32はプリプロセッサと構文解析を同時に処理してしまうため、プリプロセッサ部分だけが独立したツールとして提供されています。ヘッダファイルやマクロが正しく展開されているかどうかを確認するために使います。

●FCONVERT

テキストファイルのOEM形式とANSI形式を相互に変換するツールです。日本語環境では必要ありません。

●GREP

ソースコードなどのテキストファイルから文字列を検索するツールです。複数のファイルから、ある文字列を検索したり、指定したパターンに一致する文字列を検索できます(検索パターンなどについては、ヘルプファイルを参照してください)。

●IMPDEF/IMPLIB

IMPDEFユーティリティはDLLからモジュール定義ファイル(.DEF)を作成します。IMPLIBは、DLLに対するインポートライブラリ(.LIB)を作成します。これらのツールは、COFF2OMFの代わりにマイクロソフト製C++開発ツール向けに作成されたDLLに対応するインポートライブラリなどを作成するためにも使用できます。この場合は、互換性を向上させるために-aオプションを指定します。

●MAKE

主に複数のファイルから構成されるプロジェクトから実行ファイルを作成する際に、効率的にコンパイル・リンクを実行させるために使います。MAKEはメイクファイル(デフォルトのファイル名はmakefile)と呼ばれるテキストファイルとともに利用します。メイクファイルには、ソースコードファイル名(.cppなど)とオブジェクトファイル名(.objなど)の依存関係などを記述しておき、修正があった場合にのみコンパイル・リンクを実行させることができます。

●TDUMP

ファイルの内容をダンプ表示します。ダンプ表示とは、通常バイナリデータを16進形式で表示することです。
TDUMPでは、実行形式(.EXE/.DLL)やオブジェクト形式(.OBJ)、ライブラリ(.LIB)などを拡張子によって自動的に判別し、参照しているDLLやエクスポート関数名など、より詳細な情報を表示できます(Fig 3)。

Fig 3 実行ファイルのダンプ表示

Hide image


これらの形式のファイルを16進表示したい場合は、-hオプションを指定します。

●TLIB

ライブラリファイル(.LIB)の作成、修正、登録関数の一覧表示などに使います。BCC55には、次ページに示すとおり標準C/C++ライブラリ、コンソール関数やUNIX互換のための独自ライブラリを提供していますが、これらはTLIBを使って作成されています。開発者が独自のライブラリやクラスライブラリを作成したい場合にもTLIBを使います。

●TOUCH

指定されたファイルのタイムスタンプを更新します。MAKEを使うときに、特定のファイルのタイムスタンプを更新してコンパイルやリンクを強制できます。また、特定のファイルワイルドカード(*や?)を使って複数のファイルを指定したり、-dオプションや-tオプションを組み合わせて特定の時間や日付に指定したり、-sオプションを使ってサブディレクトリのファイルをすべて更新することもできます。

●TRIGRAPH

C/C++言語は、ASCIIという文字セットに強く依存した言語です。ANSI C/C++は、非ASCII文字セットでも利用できるように2つの「?」記号に汎用文字を追加して、ASCII依存の文字を表現できるようにしました(トライグラフシーケンス)。この機能は使用頻度が低いにも関わらず、コンパイラの処理速度を低減させます。BCC55では、ANSI C/C++に準拠しつつ高速性を維持するため、TRIGPRAHユーティリティによってトライグラフシーケンスをサポートしています。

    ライブラリに関する一般的な質問と回答

    Q. LIBフォルダにあるオブジェクトファイルやライブラリファイルは、どれを使えばよいでしょうか。

A. コマンドラインコンパイラ(BCC32)を使ってコンパイル・リンクを行う場合、Table 1に指定したオプションによって、自動的にリンカ(ILINK32)に渡されるライブラリファイルが決められます。しかし、メイクファイルを使う場合など、コンパイラとは別にリンカのみを呼び出す場合は、スタートアップモジュール(C0*.OBJ)やライブラリ(*.LIB)などを直接指定する必要があります。
ILINK32は、次のようなコマンドライン引数をとります。

ILINK32 [@respfile][options] startup objs, [exe], [mapfile], [libs], [deffile], [resfile]

ここで、それぞれの引数の意味は以下のとおりです。

Table 2 リンカの引数

respfile

応答ファイル(以下の指定をテキストファイルに記述したもの)

options

リンクオプション

startup

スタートアップモジュール(C0*.OBJ)

objs

オブジェクトファイル(.OBJ)

exe

実行ファイル(.EXE)

mapfile

マップファイル(.MAP)

libs

ライブラリファイル(.LIB)

deffile

モジュール定義ファイル(.DEF)

resfile

リソースファイル(.RES)


BCC55で提供されるスタートアップモジュールとライブラリファイルの意味をTable 3、Table 4に示します。

Table 3 スタートアップモジュールおよび特殊処理オブジェクト

C0W32.OBJ

GUI .EXE用スタートアップモジュール

C0W32W.OBJ

GUI .EXE用スタートアップモジュール(ワイド文字版)

C0D32.OBJ

DLLスタートアップモジュール

C0D32W.OBJ

DLLスタートアップモジュール(ワイド文字版)

C0D32X.OBJ

DLLスタートアップモジュール(例外処理なし)

C0X32.OBJ

32ビットコンソールモード用EXEスタートアップモジュール

C0X32W.OBJ

32ビットコンソールモード用EXEスタートアップモジュール(ワイド文字版)

FILEINFO.OBJ

オープンしているファイルハンドル情報を子プロセスへ渡すときに使う

GP.OBJ

例外処理発生時にレジスタダンプを印刷する

WILDARGS.OBJ

ワイルドカード引数を評価


Table 4 ライブラリファイル

CW32.LIB

シングルスレッドのRTL

CW32I.LIB

シングルスレッドのRTL(CC3250.DLL)用ImportLIB

CW32MT.LIB

マルチスレッドのRTL

CW32MTI.LIB

マルチスレッドのRTL(CC3250MT.DLL)用ImportLib

DXEXTRA.LIB

DirectX用スタティックLib

IMPORT32.LIB

APIのインポートライブラリ

INET.LIB

MS Internet DLL用ImportLib

NOEH32.LIB

例外処理を除外するためのライブラリ

OLE2W32.LIB

32ビットOLE 2.0API用Import Lib

OLEAUT32.LIB

32ビットOLE 2.0API用Import Lib

UUID.LIB

Direct3D、DirectDraw、シェルエクステンションなどのためのGUIDライブラリ

WININET.LIB

WININET.LIB用ImportLib

WS2_32.LIB

32ビットWinSock 2.0用ImportLib


通常のコンソールアプリケーションを作成する場合は、スタートアップモジュールにはC0X32.OBJ、ライブラリにはCW32.LIBとIMPORT32.LIBを使います。ランタイムライブラリをDLLとしてリンクする場合は、CW32.LIBの代わりにCW32I.LIBをリンクします。このときは、実行ファイルはTable 5に示すCC3250.DLLが必要です。

Table 5 ランタイムDLL

CC3250.DLL

32ビット、GUIモード

CC3250MT.DLL

32ビット、GUIモード(マルチスレッド版)


BCC55で作成するアプリケーションの実行ファイルのサイズは、最低でも50KB程度になります。これには例外処理のためのコードが含まれていますが、NOEH32.LIBを指定して例外処理を扱わないようにすることで、15KB程度プログラムサイズを節約できます(ただし、C++の入出力クラスなど例外処理が必要な場合は無効です)。

また、WindowsのGUIアプリケーションを作成する場合は、スタートアップルーチンにC0W32.OBJを使います。C0X32.OBJとC0W32.OBJの違いは、アプリケーションのエントリーポイントがmainかWinMainであることと、コンソール画面を使うかどうかであり、標準ライブラリやインポートライブラリは同じものを使います。

たとえば、コンソールアプリケーションでも、Windows APIを使用してウィンドウを表示したり、メッセージループを使うことができます。GUIアプリケーションの場合はコンソール画面がないので、コンソール入出力関数は利用できません。

マルチスレッド用のライブラリ(CW32MT.LIBやCW32MTI.LIB)は、Table 1の-WMオプションが指定するときに使います。マルチスレッドライブラリでは、ストリーム入出力などをスレッド対応にするため若干パフォーマンスに影響することがあります。C++を学習するためにコンソールアプリケーションを作成する場合など、マルチスレッドを使わないことがわかっているときは、指定しない方がよいでしょう。

    コンパイル時のトラブルに関する一般的な質問と回答

    Q. インストール後に、コマンドラインでBCC32と入力しましたが「コマンドまたはファイル名が違います」というエラーメッセージが表示されました。

A. BCC55のインストーラは、ファイルをコピーするだけで、任意のフォルダからコマンドラインツールを呼び出すためのパス(PATH)を設定しません。以下の手順でパスを設定してください。

●Windows 95/98の場合

コンソール画面を呼び出します。
コマンドラインでCD \と入力します(カレントディレクトリがC:\に移動します)。
EDIT AUTOEXEC.BATと入力します。
テキストの最後に「PATH=%PATH%;C:\BORLAND\BCC55\BIN」と入力します。
テキストを保存して、終了します。
システムを再起動します。
直接PATHを変更すれば、再起動は不要です。

●Windows NT 4.0の場合

デスクトップにある「マイコンピュータ」アイコンを右クリックし、[プロパティ]を選びます。
[環境設定]タブを選び、[システム環境変数]のPATHを選びます。
変数として「PATH」が表示されるので、値に「;C:\BORLAND\BCC55\BIN」を追加します。
[設定]ボタンを押します。
[OK]ボタンを押して、プロパティダイアログを閉じます。

●Windows 2000の場合

デスクトップにある「マイコンピュータ」アイコンを右クリックし、[プロパティ]を選びます。
[詳細]タブを選び、[環境変数]ボタンを押します。
システム環境変数のPATHを選び、[編集]ボタンを押します。
値に「;C:\BORLAND\BCC55\BIN」を追加します。
[OK]ボタンを押します。
[OK]ボタンを押して,プロパティダイアログを閉じます。

●Windows XPの場合( ※ C++ Compiler 5.5 の動作確認は行われておりません)

エクスプローラを起動し、デスクトップにある「マイコンピュータ」アイコンを右クリックし、[プロパティ]を選びます。
[詳細設定]タブを選び、[環境変数]ボタンを押します。
システム環境変数のPathを選び、[編集]ボタンを押します。
値に「;C:\BORLAND\BCC55\BIN」を追加します。
[OK]ボタンを押します。
[OK]ボタンを押して,プロパティダイアログを閉じます。

    Q. プログラムをコンパイルしようとしたら、「インクルードファイルxxx.hをオープンできない」というエラーが発生しました。あるいは、プログラムをコンパイルしようとしたら、リンカが「Unable to open file 'C0X32.OBJ'」というエラーメッセージを表示しました。

A. コマンドラインコンパイラのパスが設定した後、インクルードファイルやライブラリファイルの場所を指定したBCC32.CFGを作成しなければなりません。これは、List 4のようなファイルです。

List 4 BCC32の設定(BCC32.CFG)

-IC:\Borland\Bcc55\Include
-LC:\Borland\Bcc55\Lib

コマンドラインコンパイラは、コンパイルが成功すると自動的にリンカ(ILINK32)を呼び出します。場合によっては、リンカを明示的に呼び出すことがあります。この場合は、同様にILINK32.CFGファイルを設定してください。

また、BCC32.CFGやILINK32.CFGには、これ以外にもコンパイラやリンカに設定するオプションをあらかじめ指定できます。

    Q. ソースコードをコンパイルしたところ「致命的エラー: error 指令: Must use C++ for xxx」というエラーが発生しました。プログラムをC++としてコンパイルするには、どうすればよいでしょうか。

A. bcc32は、コマンドライン引数に指定されたファイル名の拡張子をもとに、そのファイルをCまたはC++としてコンパイルします。

拡張子が指定されていない場合は、そのファイル名に.cppという拡張子を付けたものを探してC++としてコンパイルします。

また、.cppという拡張子が指定されていればC++として、.cという拡張子が指定されていればCとしてコンパイルします。

.cという拡張子のソースコードをC++としてコンパイルする場合は、-Pオプションを指定します。-Pcxxオプションを指定するとC++としてコンパイルするデフォルトの拡張子を.cxxに指定できます。

    Q. プログラムをコンパイルすると、「外部シンボル 'WinMain' が未解決」というエラーが発生します。

A. WindowsのGUIアプリケーションを作成するために-Wオプションを指定すると、アプリケーションのエントリポイントはmainではなくWinMainになります。明示的にこのオプションを指定していないか、あるいは前述した設定ファイル(BCC32.CFG)に-Wオプションが含まれていないかどうか確認してください。

-Wオプションを指定した場合でも、必ずしもウィンドウクラスやメッセージループを使う必要はありません。List 5は、メッセージボックスを表示するだけの簡単なアプリケーションの例です。

List 5 ソースコードの例(hello.cpp)

#include <windows.h>
int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    MessageBox(0, "Hello, World!", "Welcome", MB_OK);
    return 0;
}

    Q. 以下のプログラムがエラーになります。他のC++コンパイラではエラーになりません。なぜでしょうか。

List 6 エラーになるプログラム

#include <stdio.h>
    ...
    for (int sum = 0, i = 1; i <= 10; i++)
        sum += i;
    printf("sum = %d\n", sum);

A. for文で定義された変数のスコープは、for文のブロック内に限られます。ANSI C++を制定途中では、この場合のスコープがブロック外に及ぶとされていたことがあり、古い仕様に基づいて作成されたコンパイラと動作が異なる場合があります。BCC55は、最新のANSI C++に準拠しているため、このようなコンパイラと互換性がない場合があります。なお、このプログラムの場合は、変数定義をfor文の直前に移動させてください。


ご案内 このページは、『Cマガジン』2000年7月号(ソフトバンク)に掲載されたものを、同編集部の許諾を得て掲載しています。(一部の回答は、変更されています)




Server Response from: ETNASC01