Visual C++ の古いプロジェクト、具体的には Visual C++ 2013 より前のプロジェクトで、
キャラクタバッファにフォーマット文字列を設定する
sprintf 関数
を利用していると、
マイクロソフト公式ドキュメントにも書かれているように、 sprintf 関数では書き込み文字数を制限する方法がありませんので、 バッファオーバーランが起きる可能性があります。 バッファに書き込む最大文字数を指定できる _snprintf 関数 や、どれだけバッファがあれば足りるかを調べる _scprintf 関数 の使用が推奨されています。
バッファオーバーランとは、例えば 16 バイトしか用意していないバッファに 20 文字(バイト)書き込みしてしまうと、
4 バイト、
ここでは、どのように回避すればよいか、検討しています。
なお、本サイトのご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。
投稿 June 12, 2020
ここでは、VC++ 2013 のプロジェクトを VC++ 2015 で開いてビルドするときのエラーについて書いていますが、 本題のリンクエラーが出る前に、
D8016 コマンドライン オプション '/ZI' と '/Gy-' は同時に指定できません
が出て、リンクに至りませんでしたので、先に触れておきます。
プロジェクトのプロパティを見ると、これらのコマンドライン オプションの意味がわかります。 「プロジェクト」メニューの一番下、 「<プロジェクト名> のプロパティ」を選ぶと表示されます。
/ZI は、左側 C/C++ の 全般 で指定しています。
「デバッグ情報の形式」の「エディット コンティニュのプログラム データベース」のが選ばれている場合、
/ZI が設定されています。
ここに <別のオプション> と表示されている場合は、ダイアログ左上の「構成」が「すべての構成」になっているなど、
複数選択されている構成で異なるオプションが指定されていますので、「Debug」に変更するなどして、値を確認します。
これを「プログラム データベース」に変更すると、ビルドが通るようになります。
ただし、試していませんが、
/Gy- は、左側 C/C++ の コード生成 で指定しています。 「関数レベルでリンクする」の「いいえ」の設定が、/Gy- です。 「はい」にすると /Gy となり、この設定は回避できます。
同時に指定できないだけですので、両方変える必要はありません。 エディットコンティニュの機能を使用しないなら、最初の設定を変えるだけで、ビルドが通るようになります。
投稿 June 12, 2020
ビルドが通るようになっても、_sprintf などの関数を使用していれば、エラーになります。
1>ライブラリ名.lib(モジュール名.obj) : error LNK2019: 未解決の外部シンボル _sprintf が関数 ..1.4_1.except で参照されました。 1>.\Debug\プロジェクト名.exe : fatal error LNK1120: 1 件の未解決の外部参照
自分のコード内にあるのであれば、 _snprintf 関数 (第 2 引数でコピーする最大文字数をを指定)や、 _snprintf_s 関数 (さらにバッファサイズも指定)に置き換えれば、安全になります。
唯一気をつけるべきことは、旧コードで実はバッファオーバーランして動作していた場合、 安全な関数に置き換えれば、文字列の末尾が切れるなど、従来と同じにはならない可能性です。 ただ、そんなことが発生するようなコードなら、いずれにせよ修正しないと危険ですが。
大量に使用されている場合でも、頑張って置き換えれば、それで OK です。
しかし、_sprintf 関数がライブラリで使用されている場合、特にそれがソースコードのない、外部のライブラリの場合、置き換えようがありません。 が、ライブラリごと別のものに変更するのも大変です。
こういう場合、次のようにすれば回避可能です。
図のように、プロジェクトのプロパティを開き、 左側「リンカー」の「入力」を選択します。 右側の「追加の依存ファイル」には何も書かれていないと思いますので、 空白部分をクリックし、legacy_stdio_definitions.lib と記入すると、 古い呼び出しが有効となり、ビルドが通るようになります(図では Debug 版だけですが、Release 版でも同様です)。
もちろん、これは一時しのぎであり、 少なくともこれ以降の自分のコードでは、より安全な関数を使用すべきです。
とはいえ、どうにもならないときには、こういう方法が用意されていると嬉しいですね。
GetVersionEx 関数が使えなくなり、どうやって Windows のバージョンを確認すればいいか、検討しています。 また、32 ビット OS で動作しているか、64 ビット OS で動作しているかの判定にもトライしています。
すでにインストールされている Visual Studio Community 2019 をアンインストールし、 Visual Studio Community 2022 のインストールを、実際に操作しながら記録しています。
Visual Studio Community 2019 を共存インストールする(デスクトップ)
VS 2019 をメイン デスクトップ機に共存インストールした様子を、書いています。 システムドライブの容量を節約し、データドライブにインストールされるようにしています。