-1

32 ビット バイナリを生成するために VS 2003 を使用してビルドされたコードは、単一の警告なしでビルドされました。

同じコードで、コードを 1 回も変更することなく、コンパイルとリンクは、Visual Studio 2010 コンパイラを使用して 64 ビット バイナリを生成することで成功しますが、以下の警告リストが表示されます。

だから、私の質問は、以下のリストの警告は実行時に懸念されますか?

pcd.c(248) : warning C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

pcd.c(377) : warning C4244: '=' : conversion from 'uintptr_t' to 'ULONG', possible loss of data

pcd.c(236) : warning C4100: 'argv' : unreferenced formal parameter


i.c(183) : warning C4100: 'lpReserved' : unreferenced formal parameter

api.c(506) : warning C4996: 'stricmp': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _stricmp. See online help for details.

api.c(554) : warning C4310: cast truncates constant value

api.c(719) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

api.c(2217) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

api.c(2892) : warning C4312: 'type cast' : conversion from 'ULONG_T' to 'HANDLE_T' of greater size

api.c(559) : warning C4702: unreachable code


stdio.h(234) : see declaration of 'fopen'


api.c(2217) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

prm.c(681) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h(234) : see declaration of 'fopen'


host.c(410) : warning C4311: 'type cast' : pointer truncation from 'PVOID_T' to 'unsigned long'


stub.c(138) : warning C4295: 'eye' : array is too small to include a terminating null character


isv.c(372) : warning C4310: cast truncates constant value


chp.c(250) : warning C4244: '=' : conversion from 'SOCKET' to 'ULONG_T', possible loss of data

api.c(665) : warning C4311: 'type cast' : pointer truncation from 'HANDLE_T' to 'LONG'

api.c(1216) : warning C4057: 'function' : 'LPDWORD' differs in indirection to slightly different base types from 'LONG_T *'

hlp.c(1171) : warning C4057: 'function' : 'LPDWORD' differs in indirection to slightly different base types from 'LONG_T *'


neto.c(435) : warning C4057: 'function' : 'PLONG_T' differs in indirection to slightly different base types from 'ULONG_T *'


neto.c(595) : warning C4152: nonstandard extension, function/data pointer conversion in expression

neto.c(2115) : warning C4213: nonstandard extension used : cast on l-value

neto.c(2209) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'LONG *'

td.c(760) : warning C4244: '=' : conversion from 'uintptr_t' to 'int', possible loss of data

td.c(2104) : warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'PVOID'

msc.c(287) : warning C4133: 'function' : incompatible types - from 'long *' to 'time_t *'


msc.c(1009) : warning C4702: unreachable code


inf.c(400) : warning C4057: 'function' : 'PLONG_T' differs in indirection to slightly different base types from 'ULONG *'

arb.c(166) : warning C4267: '=' : conversion from 'size_t' to 'LONG_T', possible loss of data

arb.c(226) : warning C4244: '=' : conversion from 'int' to 'CHAR_T', possible loss of data

sl.c(441) : warning C4054: 'type cast' : from function pointer 'int (__cdecl *)(unsigned char *,int,int,void *)' to data pointer 'void *'


pco.c(369) : warning C4057: 'function' : 'PLONG_T' differs in indirection to slightly different base types from 'ULONG_T *'

exit1.c(157) : warning C4295: 'publickey' : array is too small to include a terminating null 


env.c(341) : warning C4267: 'function' : conversion from 'size_t' to 'DWORD', possible loss of data

hook.c(221) : warning C4245: 'return' : conversion from 'int' to 'SOCKET', signed/unsigned mismatch

hook.c(817) : warning C4311: 'type cast' : pointer truncation from 'unsigned char *' to 'int'

tor.c(128) : warning C4244: 'function' : conversion from 'time_t' to 'unsigned int', possible loss of data


cth.c(1012) : warning C4244: '=' : conversion from '__int64' to 'int', possible loss of data


cntrl.c(427) : warning C4996: 'strnicmp': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strnicmp. See online help for details.


api.c(263) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'LONG_T *'

api.c(706) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'DWORD *'

ii.c(252) : warning C4244: '=' : conversion from 'time_t' to 'long', possible loss of data

どうも

4

3 に答える 3

6

エラーメッセージを読むのが上手になることをお勧めします。それらは平易な言葉で書かれています。まだ理解していない用語については、Google で検索できます。

たくさんやってみましょうか?

pcd.c(248) : 警告 C4996: 'getenv': この関数または変数は安全でない可能性があります。代わりに _dupenv_s の使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。

getenv別のスレッドから変数を変更しているときに呼び出す場合にのみ、これについて心配します。これらのルーチンの問題は、それらがグローバルな状態に依存していることです。これは、複数のスレッドが使用されている場合に問題になります。新しいバージョンでは、誰がどの割り当てを所有しているかについても明確になっています。

pcd.c(377) : 警告 C4244: '=' : 'uintptr_t' から 'ULONG' への変換、データが失われる可能性があります

不審に見えます。ポインターを整数にキャストすることでファンキーなことをしていますか? 64ビットWindowsが導入された頃、彼らはこれを追加ULONG_PTRしました.

pcd.c(236): 警告 C4100: 'argv': 参照されていない仮パラメーター

ic(183): 警告 C4100: 'lpReserved': 参照されていない仮パラメーター

安全に無視または抑制できます。

api.c(506): 警告 C4996: 'stricmp': このアイテムの POSIX 名は非推奨です。代わりに、ISO C++ 準拠の名前 _stricmp を使用してください。詳細については、オンライン ヘルプを参照してください。

さほど気になりません。アンダースコアを含む名前は、*nix システムでの移植性が低下する可能性があります。

api.c(554) : 警告 C4310: キャストは定数値を切り捨てます

不審に見えます。例を挙げてください。

api.c(719): 警告 C4996: 'strcpy': この関数または変数は安全でない可能性があります。代わりに strcpy_s の使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。

api.c(2217): 警告 C4996: 'sprintf': この関数または変数は安全でない可能性があります。代わりに sprintf_s の使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。

これらは、すべてのまともな C プログラマーが知っている、または理解しておくべき古くからの問題です。Google 検索を行うか、バッファ オーバーフローと、可能な限りこれらの関数を避ける必要がある理由について読んでください。_s名前は C1x 標準にありますが、*nix システムではあまり一般的ではない可能性があることに注意してください。古い規格に準拠したともsnprintfあります。strncpy

api.c(2892) : 警告 C4312: '型キャスト': 'ULONG_T' からより大きなサイズの 'HANDLE_T' への変換

よくわかりませんHANDLE_Tが、Win32 ではHANDLEポインタのサイズです。これはかなり悪いです。以前のように提案ULONG_PTRします。

api.c(559) : 警告 C4702: 到達できないコード

まさにそれが言うこと。

stdio.h(234) : 'fopen' の宣言を参照してください

あなたはそれを見ましたか?

api.c(2217): 警告 C4996: 'sprintf': この関数または変数は安全でない可能性があります。代わりに sprintf_s の使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。

上記と同様。

prm.c(681) : 警告 C4996: 'fopen': この関数または変数は安全でない可能性があります。代わりに fopen_s の使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h(234) : 「fopen」の宣言を参照

これは、MS コンパイラが推奨し始めた別の C11 機能です。これはちょっと疑わしいです。 fopenおそらくOKです。必要に応じてドキュメントをお読みください。

host.c(410) : 警告 C4311: 'type cast' : 'PVOID_T' から 'unsigned long' へのポインターの切り捨て

の代わりにULONG_PTRまたはを使用します。uintptr_tunsigned long

stub.c(138) : 警告 C4295: 'eye' : 配列が小さすぎて、終端の null 文字を含めることができません

私の推測では、次のような文字列を宣言しました。

char foo[n] = "blah";

n小さすぎて紐が収まらないサイズはどこですか。整数を削除するだけです。

api.c(1216) : 警告 C4057: '関数' : 'LPDWORD' は、'LONG_T *' とはわずかに異なる基本型に対して間接的に異なります

DWORDLONGは異なる型であり、一方へのポインターを取得し、それを他方として使用しています。これは違法です。(この場合、問題は発生しませんが、修正する必要があります。)

neto.c(595) : 警告 C4152: 非標準拡張機能、式での関数/データ ポインター変換

うーん、どうやってこれをやったのかわからない。多分あなたは関数ポインタをに割り当てましたvoid *か?標準では技術的に違法ですが、これを必要とするライブラリがいくつかあります。

neto.c(2115) : 警告 C4213: 非標準の拡張子が使用されています: 左辺値にキャスト

私の推測では、あなたは次のようなことをしたと思います:

*(char*)foo = bar;

違法。

neto.c(2209) : 警告 C4057: 'function' : 'int *' は、'LONG *' とはわずかに異なる基本型に対して間接的に異なります

と を交互に使用するPDWORDのと同様の状況。LONG

td.c(2104) : 警告 C4054: '型キャスト' : 関数ポインター 'FARPROC' からデータ ポインター 'PVOID' へ

neto.c の 595 行目と同様です。

于 2013-01-23T08:10:44.887 に答える
5

はい:

未定義の動作を引き起こすものがいくつかあります。

すべての警告は (少なくともあなたの考えでは) 論理的なエラーと見なされるべきであり、確認して沈黙させるべきです。コードを明示的に変更するか、コンパイラ ディレクティブを使用して警告を無効にするかのいずれかです (その後、警告を無効にした理由について長いコメントを書きます。これは、警告が意図的に調べられたことも示しています)。

最初にチェックするものの簡単なスキャン (重複を削除)。

これらは間違いなく悪いように聞こえます:

stub.c(138) : warning C4295: 'eye' : array is too small to include a terminating null character
exit1.c(157) : warning C4295: 'publickey' : array is too small to include a terminating null 

これらは悪いかもしれません:

api.c(554) : warning C4310: cast truncates constant value

chp.c(250) : warning C4244: '=' : conversion from 'SOCKET' to 'ULONG_T', possible loss of data

api.c(1216) : warning C4057: 'function' : 'LPDWORD' differs in indirection to slightly different base types from 'LONG_T *'

neto.c(2209) : warning C4057: 'function' : 'int *' differs in indirection to slightly different base types from 'LONG *'

td.c(760) : warning C4244: '=' : conversion from 'uintptr_t' to 'int', possible loss of data

msc.c(287) : warning C4133: 'function' : incompatible types - from 'long *' to 'time_t *'

arb.c(166) : warning C4267: '=' : conversion from 'size_t' to 'LONG_T', possible loss of data

arb.c(226) : warning C4244: '=' : conversion from 'int' to 'CHAR_T', possible loss of data

api.c(665) : warning C4311: 'type cast' : pointer truncation from 'HANDLE_T' to 'LONG'

これらはコードに残しませんが、おそらく無害です。

api.c(559) : warning C4702: unreachable code

td.c(2104) : warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'PVOID'
于 2013-01-23T08:03:39.943 に答える
3

警告には次の 3 種類があります。

  1. 安全でない/非推奨の関数に関する警告。これらの関数は安全ではない/非標準であり、おそらく以前に廃止されたため、これらの警告のいくつかは以前に受け取った可能性があります。ただし、それらを見て、正しく使用することを確認した場合 (64 ビットでは一部の型のサイズが変更されることに注意してください)、引き続き使用できます。ただし、可能な場合は標準関数を使用するようにします。関数を正しく使用することが確実な場合は、少なくとも警告を個別にオフにする必要があります。

  2. 「参照されていないパラメーター」、符号付き/符号なしの不一致、到達不能なコード、および警告 C4295、C4054、C4133 などの厄介なものなど、以前にもあったはずの警告。それらをすべて修正する必要があります。それほど重大ではないものもありますが (例: 符号付き/符号なしの不一致)、修正は非常に簡単です。

  3. MSVC を使用する Windows で 64 ビットのサイズが異なるために発生する警告。32 ビットでは、int、long、long long、ポインタ、size_t などは 32 ビット サイズです。データを失うことなく、シームレスに変換できます。ただし、64 ビットでは、long long、size_t、およびポインターのサイズは 64 ビットですが、long と int は 32 ビットのままです。それらを変換すると、特にポインターが関係している場合、情報が失われる可能性があります。正しい型を使用するようにしてください。縮小変換は使用しないでください。これは、PVOID、DWORD、および同じものに別の名前を付けるために WinAPI が使用するすべての typedef など、これらの型のさまざまな typedef にも当てはまります。

一般的に: 警告には理由があります。個々の警告に注意を払い、適切な変更をコードに適用することで、コンパイラを可能な限り黙らせるようにしてください。絶対に変換を行う必要があり、変換がプログラムの有効性に影響を与えないことが確実な場合は、明示的なキャストを使用します (つまりstatic_cast、ほとんどの場合)。そうすることで、プログラム全体を完全に壊してしまい、何日もかけてデバッグするまで発見されない、本当にばかげた間違いを示唆する単一の警告を見逃さないようにすることができます。特に 32/64 ビットのデュアル プラットフォーム コンパイルでは面倒ですが、長期的には努力する価値があります。

于 2013-01-23T08:25:10.473 に答える