トップ回答者
/GSオプションによるバッファーオーバーランの抑止ついて

質問
-
VC2008とVC2012でアクセス違反しているコードを実行するとVC2008は動作しVC2012は実行エラーになります。
VC2008とVC2012では「/GS」のチェックレベルが異なるのでしょうか?
どちらも「/GS」オプションはオンになっています。
VC2008:「構成プロパティ」-「C/C++」-「コード生成」-「バッファセキュリティチェック」=はい を選択
VC2012:「構成プロパティ」-「C/C++」-「コード生成」-「セキュリティチェック」=はい(/GS) を選択
以下、検証プログラム(注:アクセス違反有り)
void main(void)
{
char strA[8];
char strB[8];
strA[8] = '\0'; /*アクセス違反*/
strB[8] = '\0'; /*アクセス違反*/
}
回答
-
/GS コンパイラ オプションが変更され、旧バージョンよりバッファー オーバーランが包括的に回避されるようになりました。 このバージョンでは、追加のセキュリティ チェックがスタックに挿入される場合があり、そのためにパフォーマンスが低下する可能性があります。 コンパイラに対し、特定の関数にセキュリティ チェックを挿入しないことを指定するには、新しい __declspec(safebuffers) キーワードを使用します。
という記述があります。またVC++2010の/GSオプションと2008の/GSオプションは記述内容がちょこちょこ異なります。
次に実際の動作ですが、
- VC++ 2008 Debug メソッドを抜ける際にエラー
- VC++ 2008 Release チェックされず
- VC++ 2015 Debug アクセス時にエラー
- VC++ 2015 Release アクセス時にエラー
という結果になりました。これはVC++ 2008の/GSオプションに「最適化が無効な場合にセキュリティ保護を行いません」旨の記述がありますがこれが真逆で「最適化が有効な場合にセキュリティ保護を行わない」という印象です。(英語版にも同様の記述があり翻訳ミスではありませんでした。)
というわけで、VC++ 2010からは最適化が有効であってもチェックが行われる、が答えになるかと。
- 回答としてマーク ms.sh 2015年8月25日 12:57
すべての返信
-
/GS コンパイラ オプションが変更され、旧バージョンよりバッファー オーバーランが包括的に回避されるようになりました。 このバージョンでは、追加のセキュリティ チェックがスタックに挿入される場合があり、そのためにパフォーマンスが低下する可能性があります。 コンパイラに対し、特定の関数にセキュリティ チェックを挿入しないことを指定するには、新しい __declspec(safebuffers) キーワードを使用します。
という記述があります。またVC++2010の/GSオプションと2008の/GSオプションは記述内容がちょこちょこ異なります。
次に実際の動作ですが、
- VC++ 2008 Debug メソッドを抜ける際にエラー
- VC++ 2008 Release チェックされず
- VC++ 2015 Debug アクセス時にエラー
- VC++ 2015 Release アクセス時にエラー
という結果になりました。これはVC++ 2008の/GSオプションに「最適化が無効な場合にセキュリティ保護を行いません」旨の記述がありますがこれが真逆で「最適化が有効な場合にセキュリティ保護を行わない」という印象です。(英語版にも同様の記述があり翻訳ミスではありませんでした。)
というわけで、VC++ 2010からは最適化が有効であってもチェックが行われる、が答えになるかと。
- 回答としてマーク ms.sh 2015年8月25日 12:57