2011-09-11 5 views
7

このファイルのコンパイル時にGCCは私にの同一の警告を示し、なぜ私は好奇心が強い:GCCは、不正なprintfフォーマット指定子に対して重複した警告を表示するのはなぜですか?

$ clang test.c 
test.c:6:14: warning: conversion specifies type 'int' but the argument has type 'long' [-Wformat] 
    printf("%i\n", foo); 
      ~^  ~~~ 
      %ld 
test.c:6:14: warning: conversion specifies type 'int' but the argument has type 'long' [-Wformat] 
    printf("%i\n", foo); 
      ~^  ~~~ 
      %ld 
2 warnings generated. 

任意のアイデア:

$ cat test.c 
#include <stdio.h> 

int main (int argc, char const *argv[]) 
{ 
    long foo = 0l; 
    printf("%i\n", foo); 

    return 0; 
} 
$ gcc-4.2 -Wall test.c 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 

は興味深いことに、クランは、2回の警告を与えますか?詳細については


$ gcc-4.2 -v 
Using built-in specs. 
Target: i686-apple-darwin11 
Configured with: /private/var/tmp/gcc/gcc-5666.3~278/src/configure 
--disable-checking --enable-werror --prefix=/usr --mandir=/share/man 
--enable-languages=c,objc,c++,obj-c++ 
--program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib 
--build=i686-apple-darwin11 --program-prefix=i686-apple-darwin11- 
--host=x86_64-apple-darwin11 --target=i686-apple-darwin11 
--with-gxx-include-dir=/include/c++/4.2.1 
Thread model: posix 
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3) 

$ clang -v 
Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn) 
Target: x86_64-apple-darwin11.1.0 
Thread model: posix 

EDIT: 'マルチアーキテクチャ' 仮説の数は、良い響きを示唆しているが、私はそれが正しいだか分かりません。私が-archで単一のアーキテクチャを強制すると、2つの警告が出ます。 -arch x86_64 -arch i386と指定すると、重複した警告が2セットあります。

$ gcc-4.2 -Wall -arch x86_64 test.c 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 

$ gcc-4.2 -Wall -arch x86_64 -arch i386 test.c 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c: In function ‘main’: 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 

編集:私は、すべての警告のタイプのdupesを得ることはありません。 -Wformatは私がこれまで出会った唯一のものです。たとえば、私が未使用の変数を投げた場合、そのことについて警告が1つだけ得られます。

$ cat test.c 
#include <stdio.h> 

int main (int argc, char const *argv[]) 
{ 
    long foo = 0l; 
    long bar; 
    printf("%i\n", foo); 

    return 0; 
} 

$ gcc-4.2 -Wall test.c 
test.c: In function ‘main’: 
test.c:7: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:7: warning: format ‘%i’ expects type ‘int’, but argument 2 has type ‘long int’ 
test.c:6: warning: unused variable ‘bar’ 
+2

FWIW、私は唯一のエラーメッセージが表示されます。これはあなたのビルドシステムの成果物ではないと確信しています。これは何とかGCCを2度呼びますか? –

+0

ありがとうございました。私は全くわからない、それはおそらくそうである。: -/ –

+0

重複する警告が表示されません。しかし、それはあなたがとにかく修正する必要があるという警告です... –

答えて

8

これは、Appleのstdio.hヘッダはprintf()のその宣言にGCC format attributeを添付するので...

ある

(例えばprintf()hereの宣言と__printflike()マクロhereの宣言を参照してください)...しかし、 GCC(とClangは非常にGCCと互換性があるために!)は、printf()printfスタイルの引数を取る関数であることを既に知っています。組み込みの知識と、明示的な属性による2番目の警告のため警告が1つ表示されます。

あなたが同じことを自分で行うことによって(GCCの少なくともいくつかのバージョンで)他のプラットフォームで同じ動作を実証することができます:私は、GCC 4.1.2を使用する場合

extern int printf(const char *, ...) __attribute__((__format__ (__printf__, 1, 2))); 

int main (int argc, char const *argv[]) 
{ 
    long foo = 0l; 
    printf("%i\n", foo); 

    return 0; 
} 
+0

Brilliant!問題が解決しました。 (/ usr/include/stdio.hの 'printf'の定義から' __DARWIN_LDBL_COMPAT(printf)__printflike(1、2) 'を削除してから再コンパイルすることで、これが正解であることを証明することもできます)。 –

2

iOS用にコンパイルされているようです。コードは複数のアーキテクチャで複数回コンパイルされています。警告は各アーキテクチャに対して生成されています。

+1

マルチアーキテクチャの説明は理にかなっていますが、ここではそうは確かではありません。たとえば、 '-arch x86_64'をgccまたはclangフラグに追加すると、重複した警告が表示されます。 '-arch x86_64 -arch i386'を追加すると、4つの警告が表示されます。 :) –

+1

-1:明らかに彼はiOS用にコンパイルしていないし、マルチアーチビルドも行っていない。コンパイラの呼び出しは質問で指定されます。 –

3

コンパイラが各ファイルに対して2回実行されるため、2つのCPUアーキテクチャ(iOS上のARMv6/ARMv7、Macではi386/x86_64)を対象としています。

PPC/PPC64サポートを有効にすると、Macでは、1行に最大4つの警告が表示されます。 ;)

を編集してください:Matthew'sは、受け入れられた答えにスポットを当てました。

関連する問題