2017-10-12 6 views
3

strlenの返品はsize_tです。これはlong unsigned intです。strlenの出力をintに格納するときに警告が表示されないのはなぜですか?

なぜ次のコードをコンパイルしても、符号度がslenであることに関する警告は表示されません。

char msg[] = "Hello"; 
int slen= strlen(msg); 

(私はlong unsigned int slenは、このような警告を回避するために必要であったであろうことを期待。)

+3

おそらくコンパイラの設定に依存します。 –

+5

する必要はありません。この変換は完全に合法です。 –

+1

GCCの['-Wconversion'](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) – DaBler

答えて

6

CおよびC++言語は、(コンパイラがあなたに与えることができるあなたは警告なしに、すべての異なる種類の間の整数をコピーしてみましょう警告はデフォルトではcharとなりますが、これは有名な例外です)。

gccを使用すると、この警告を使用して上位ビットが失われないようにすることができます(したがって、long longintは32ビットマシンで警告を表示します)。

gcc ... -Wstrict-overflow ... 

自動変換を防ぐためのフラグもあります:

gcc ... -Wno-int-conversion ... 

コンパイルの問題の多くを引き起こす可能性があるが、あなたのコードをテストすることをお勧めすることができ(lintはタイプのもの)。

gccマニュアルを見ると、これらの警告に関するその他の詳細がわかります。

警告をエラーに変換するには、-Werrorフラグを使用することもできます。そうすれば、あなたはバグを考えていることを続ける代わりにコンパイルが失敗します。

+4

"デフォルトでは、CおよびC++では、警告なしですべての異なる型間で整数をコピーできます。" - 言語が*警告*を必要としないと言うのがより正確です。コンパイラは好きなことについて警告することができ、C標準ではコンパイラのデフォルト動作を何にするべきかは何も言いません。これは、構文規則と制約(これはそうではありません)の違反に対して診断を発行するコンプライアントコンパイラを必要とするだけであり、多くのコンパイラはデフォルトでも準拠していません。 –

-3

strlenは文字列関数です。つまり、アドレスとして引数を指定する必要があります。かっこなしのmsgは、最初の要素のアドレスを引数として与えることを意味します。 strlen関数は、終了ヌル文字を含まない配列内の単語の数を計算します。つまり、intを返すという意味で、この例ではslen = 5

+0

これは単語ではなくバイト数です。 Win2k以来ずっとあまり使われていないUSC-16は、いくつかの単語(1文字あたり2バイト)になるでしょう。 –

+0

単語ではなく文字の数です。 'strlen'は' int'ではなく 'size_t'を返します。 –

+0

@RetiredNinja、no、 'strlen()'はバイト数をカウントし、最初の '\ 0 'で停止します。 'wchar_t'(Windows上の単語、' wcslen() ')、またはUTF-8文字列(' mbslen() ')を数えるにはマルチバイト関数が必要です。 –

関連する問題