VC++のコンパイル警告

昔のVC++プロジェクトを、Visual Studio2019に取り込んだが、古いソースで、最新ではコンパイル警告がいくつか出る。

(コンパイラバージョン別の警告の一覧)

https://docs.microsoft.com/ja-jp/cpp/error-messages/compiler-warnings/compiler-warnings-by-compiler-version?view=msvc-160

だいぶ昔のソースを取り込んだのもありも、VSも以前よりチェック項目が増えていて結構な数の警告が出た。警告は無視しても動くが、警告を直していくことでいい勉強になることもある。

C4589:Constructor of abstract class ‘type’ ignores initializer for virtual base class ‘type’

 抽象クラス  ’VBase2 ’のコンストラクターは仮想基底クラス 'VBase’ を無視します

これは、仮想基底クラスVBaseを継承する抽象VBase2のコンストラクター定義で、書かなくていい VBase の定義を書いていたということ。抽象クラスを継承した抽象クラスだけど、何となく実装クラスのイメージでコンストラクターのコードを書いて警告が出たということでした。

class VBase
{
public:
	VBase(const int param);
	virtual ~VBase() {};
	
	virtual void mustOverrideMethod() = 0;

private:
	int _param;
};

VBase::VBase(const int param)
{
	_param = param;
}

class VBase2 : public virtual VBase
{
public:
	VBase2(const int param);
	virtual ~VBase2() {};

	virtual void mustOverrideMethod2() = 0;
};

VBase2::VBase2(const int param) : VBase(param)  // ← C4589警告
{
}

この抽象クラスVBase2のコンストラクターの実装が以下。

(誤)
VBase2::VBase2( const int param ) : VBase(param )  // ← C4589警告
{
}

(正)
VBase2::VBase2( const int /* param */ ) 
{
}

VBase2自体も抽象クラスで、ここでVBaseのコンストラクターの引数を定義しても意味は無く、実装クラスで定義する必要があるということ。

class ImplVBase2 : public virtual VBase2
{
public:
	ImplVBase2(const int param);
	virtual ~ImplVBase2() {};

	virtual void mustOverrideMethod() {};
	virtual void mustOverrideMethod2() {};
};

ImplVBase2::ImplVBase2(const int param) : VBase2(param), VBase(param)   // ← ※ここでVBase(param) 定義
{
}

VBase2のコンストラクターで引数を持つ必要がそもそもないということになるが、例えばユーザークラスを実装していて、キーがユーザーNoでそれを引数としている場合には、やはり引数があった方が見た目が良いように個人的には思えるので残した。

UserImpl::UserImpl(const int userNo) : UserBaseEx( userNo ), UserBase( userNo )

↓ 

UserBaseEx::UserBaseEx( const int /* userNo */)  ※このクラスだけ、userNoが無いのもなんか違和感が・・・・

↓

UserBase::UserBase( const int /* userNo */)

C4996 :コンパイラの警告(レベル3)

古いソースのため、推奨されない関数を使っているということで、以下のメッセージが出た。

'inet_ntoa': Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings

inet_toaが非推奨で、inet_ntop()かInetNtop()を使えとのことで、inet_ntopに変えたが

https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-inet_ntop

ws2tcpip.hをインクルードしても、「inet_ntopが定義されていない」というエラーが・・・・

ws2tcpip.h の中を見てみると、バージョンチェックではじかれているよう。

https://docs.microsoft.com/ja-jp/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-170

古い古いVSで作ったもので、stdafx.hの中のバージョン定義が古すぎのため、inet_ntopの対象外となっていた。astafx.hの中のバージョン定義を変えることで解決。

Debug版のプロジェクト設定の問題

古いプロジェクトから自動移行した場合に、以下の警告が出るので設定変更が必要。

LNK4075:リンカー ツールの警告

/EDITANDCONTINUE は /SAFESEH の指定によって無視されます

追加になったデバッグ用の設定が自動でされていないため、プロジェクトの[プロパティ]-[詳細]で、[デバッグ ライブラリの使用]を「はい」に設定。

D9305:コマンド ラインの警告カー ツールの警告

オプション 'Gm' の使用は現在推奨されていません。今後のバージョンからは削除されます。

プロジェクトの[プロパティ]-[C/C++]-[コード生成]で、[最小リビルドを有効にする]を「いいえ」に設定。

その他

アプリケーションの画面

作成されたアプリケーションの画面サイズが小さくなってしまうので、 プロジェクトの[プロパティ]-[マニフェストツール]-[入出力]で、[DPI認識]を「なし」に設定。