Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ビルド時警告の削減:operator new/delete 部分 #51

Merged
merged 1 commit into from
Jun 4, 2018

Conversation

kobake
Copy link
Member

@kobake kobake commented Jun 3, 2018

operator new/delete の warning C9595 対策

  • build_config.h で inline 定義されていた operator new/delete の定義を build_config.cpp 側に移した。
  • build_config.cpp のエンコーディングを UTF-8 にする都合で、文字列定数で半角カナを使うのはやめてASCII文字列に差し替え。

関連PR

operator new/delete 部分についてはちょっと処理がややこしいので原作者 (kobake) のほうで対応。

build_config.h で inline 定義されていた operator new/delete の定義を build_config.cpp 側に移した。
build_config.cpp のエンコーディングを UTF-8 にする都合で、文字列定数で半角カナを使うのはやめてASCII文字列に差し替え。
@kobake kobake mentioned this pull request Jun 3, 2018

void* operator new[](size_t nSize)
{
void* p = ::malloc(nSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p に対して NULL チェックしないとメモリ確保に失敗したら落ちます。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 行目も同様です。
_fill_new_memory で NULL チェックするのでもいいです。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

まあ、デバッグコードですけど

Copy link
Contributor

@berryzplus berryzplus Jun 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VC++のmallocはnewMode設定によってstd::bad_alloc例外を投げます。

mallocが例外を投げる想定ならNULLチェックは不要です。

_fill_new_memoryではNULLチェックしたほうが良いです。

--
書くべき場所が違った!
と気づいたので適切な場所に転記しますm(_ _)m

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

malloc の NULL チェックについてはその通りなのですが、元々の V1 のコードでは malloc の NULL チェックはまるで行われていなかったので、挙動としてはそのまま踏襲してあります。

ただ、(デバッグビルドに限りますが)このメモリ確保ロジックを build_config.cpp に集約させることによって、プログラム各地に存在するメモリ確保処理についてのエラー対策を全て build_config.cpp に処理を追加するだけの手間で注入することができます。

本PRについてはあくまでも既存機構の Warning 除去が主目的ですので、NULL チェック自体は別件で処理したい気持ちです。

メモリ確保時の NULL チェック時の処理(ここをどうするべきかは議論の余地あり)を注入しやすい場所があるという認識は伝わったかと思いますので、今後の話として良い感じの処理を埋め込める土台として活用できればと考えています。

いくつか選択肢はあります。

  • スタックトレースや使用メモリ状況等をログ出力した上でエラーダイアログを表示して強制終了
  • メモリマップトファイル等の機構を利用して一時的に凌ぎ(凌げるかな?)、ダイアログを表示してユーザに注意を促す

どちらにしろ簡単な変更ではないので、まずは別件の Issue 等で議論を行い対応を検討するのが良いところかと思います。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

追記しておくと、今回の operator new/delete の書き換えの有無にかかわらず、プログラムの至る所でメモリ確保の NULL チェックは入っていないというのが現状です。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

意図通りのコメントが書けないのは
ぼくがGitHubの使い方を分かっていないせいか、win8.1のIE11がダメなせいか。

趣旨了解しました。
警告削減のために既存コードをまるごとcppに退避させる、という内容ならばOKです。

26行目の #if ブロックはもう要らないんじゃ・・・
というのは別の機会に指摘するようにします。←書いてるやん

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

26行目の #if ブロックはもう要らないんじゃ・・・
というのは別の機会に指摘するようにします。←書いてるやん

これは、、たぶんいらないですね。
ただこのあたりの挙動は別件としてしっかり精査してから判断させてください。(ここの #if ブロック内容は自分以外の方が挿入されたものなので、いまいち挙動を把握しきれてないです)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

既に閉じてしまっていますが参考情報を追記します。

#ifdef _MSC_VER
#if _MSC_VER == 1500
_Ret_bytecap_(_Size) // for VS2008 Debug mode
#endif
#endif
void* operator new[](size_t nSize)

ぼくが書いた「#ifブロック要らない」は、中身をそのまま記述したらいい、という意味です。
_Ret_bytecap_(_Size) という書き方はメタプログラミングの一種です。
Microsoftが提唱する SAL というもので、最近のwindowsSDKはこの書き方になってるはずです。
たしかvista以降は一律適用。msdnの関数定義もこの書き方になってますよね。
WinMain@msdn _In_ というのがSALです。

SALにはバージョンがいくつかあるようです。
個人的には、windows SDK8.1のものがシンプルで好きです。
メリットはmsdn英語サイトの解説を見てください。
デメリットはvc++以外のコンパイラ向けに空defineを用意してやる必要があることです。
昨年末くらいに試した限りではMinGWに付属のWindowsAPIヘッダはSALに対応していませんでした。
CMakeに空defineを生成する機能とかプラグインとかあったらいいな、とか思ってみたり。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

情報ありがとうございます。あとで調べてみます!

@kobake
Copy link
Member Author

kobake commented Jun 4, 2018

@m-tmatma さんのほうでも問題なければマージお願いします

Copy link
Member

@m-tmatma m-tmatma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そもそもメモリ確保の失敗した時の件は、
このチケットのスコープではありませんでした。

@m-tmatma m-tmatma merged commit 6f23813 into master Jun 4, 2018
@kobake kobake deleted the fix-operator-new-delete-warnings branch June 4, 2018 03:37
@m-tmatma m-tmatma added this to the next release milestone Jun 4, 2018
@berryzplus
Copy link
Contributor

berryzplus commented Jun 4, 2018

はぅ、衝撃の事実。

#ifdef _MSC_VER
#if _MSC_VER == 1500
_Ret_bytecap_(_Size) // for VS2008 Debug mode
#endif
#endif
void* operator new[](size_t nSize)

これが SAL だとすると書き方間違ってますね。(=SALとして機能してない)

_Ret_bytecap_(nSize)
void* operator new[](size_t nSize)  

こういうコードであれば「戻り値はnSizeバイト分のメモリ領域である」という意味の注釈になります。cl.exe /analyze したときに分析エラーになるだけで実行コードには影響を与えません。バグではないです。書いてあるコードが意味をなしていなかった、というだけです。(それもいいのか微妙...

operator newの戻り値注釈は、厳密にはもっと複雑です。
例外時は値を返さない仕様があったりするので…
書くならちゃんと書いたほうがいいのかも知れません。

berryzplus added a commit to berryzplus/sakura-editor that referenced this pull request Jun 4, 2018
@KENCHjp KENCHjp added the CI appveyor など CI 関連 【ChangeLog除外】 label Dec 5, 2018
HoppingTappy pushed a commit to HoppingTappy/sakura that referenced this pull request Jun 11, 2019
…ew-delete-warnings

ビルド時警告の削減:operator new/delete 部分
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI appveyor など CI 関連 【ChangeLog除外】
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants