2012-03-29 3 views
16

これについての情報は少し検索しましたが、満足できるものは何も見つかりませんでした。これは、(-Wallとgccの上で)警告している理由を説明する関数呼び出しgcc -Wallが長さゼロの書式文字列について警告を出すのはなぜですか?

sprintf(someString, ""); 

にいくつかの特別な行動はありますか?私は、C標準が長さゼロの書式文字列を許可していることが分かりました。

私が見に期待まさにある

'''a' 

を出力

#include <stdio.h> 

int main() 
{ 
    char str[2] = {'a', 'a'}; 
    sprintf(str, ""); 
    printf("\'%c\'\'%c\'\n", str[0], str[1]); 
    return 0; 
} 

次の例を試してみました。 なぜ、警告ですか?

+2

C++が意味しないところを見つけたところではありません... –

+1

g ++でコードをコンパイルしていたので最初はそうだと思いましたが、gccが同じ警告。 – SirGuy

+0

ああ、だれかが不思議に思っているのであれば、私は誤ってこのコードを見つけたが、実際にはそれを書かなかった。 – SirGuy

答えて

22

GCCが警告を発行するという事実は、通常、構成が正当なCであるかどうかとは関係ありませんが、GCC開発者が、あなたが書いたもの以外の何かを意味する可能性があるという印象か、いくつか例があります:

  • if (x = 0) - あなたは確かにif (x == 0)を意味します。
  • printf(str) - ほとんどの場合、fputs(str, stdout)またはprintf("%s", str)のいずれかを意味します。書かれているように、コードは非常に危険です。
  • if (foo == bar & MASK) - あなたは確かにif (foo == (bar & MASK))を意味します。あなたの場合など

、私はあなたがString[0]=0;と同等のものを行うにはsprintf(String, "")を呼んでいる理由GCCを問うていると思います(後者はより速く、非常に短く、明確)。

+1

私はそれがより良いと同意します、私はちょうど警告を考慮してそれ以上の理由があるかどうかわかりません。私は確かに権限はありませんが、合理的なプログラミングに対するこのような特定の犯罪は警告的であると考えられているとは思わない – SirGuy

+3

私は同意しますが、GCCは警告を伴うもっと厄介なことをします。これは間違いなく、より少ない犯罪です。より大きい方は、未使用の関数引数について警告を出しています。これは、特定の署名に従わなければならない関数ポインタを使用しているときはいつでも避けられません。 –

+0

ああ、以前はそのような警告が出たことはありませんでした。私はその状況が起こったのです – SirGuy

4

これは単にGCCの警告です。あなたのアプリケーションの一部のためにそれを抑制したい場合は、以下の操作を行うことができます

#pragma GCC diagnostic ignored "-Wformat-zero-length" 
int main() 
{ 
    // code that produces a warning 
} 
#pragma GCC diagnostic warning "-Wformat-zero-length" 
+1

私はそれを取り除くことができることを知っている、私はそれが始まった理由は疑問に思っていた – SirGuy

+5

私はそれがちょうど無意味で、有害な警告だと思う。これは、フォーマット文字列がプリプロセッサマクロの定義/値に応じてゼロ長でも重要でもないコードを確実に噛むことができ、そのようなコードは完全に妥当と思われます。 –

+3

それは有害ではありません。あなたのコードについて間違いがあり、誤っていると思われることがあることを知らせるだけです。 'sprintf(str、" ");は正当なものですが、_str_に長さゼロの文字列を作るのはむしろラウンド・オーバーな方法です。それは禁止されていません。ちょうどあなたの注意を引いた。 –

6

gccがsprintf()への2番目の引数は、通常、非空の文字列でなければならないことを知っているので、あなたは警告を取得していますいろいろなフォーマット仕様のもの - コードで実行しているものと機能的に同等でより合法的な呼び出しはsprintf(str, "%s", "")です。また、ほとんどの場合、N個の追加引数があり、フォーマット仕様を満たすのに十分です。ここでは、strcpy()のようなものを使用していますが、技術的には有効ですが、標準ライブラリを使用するのは非常に奇妙な方法です。

関連する問題