2

私は最近、いくつかの変数についてコードベースを float から long に変更していましたが、まだ間違っているとわかっていた領域でコンパイラによって生成されたエラー メッセージがないことを発見しました。これにより、コンパイラ フラグに -Wconversion を追加することになりました。しかし、おっと、これはいくつかの偽のエラーメッセージにつながります. 以下のスニペットでは、前述のエラーが発生します。ケースバイケースでこのメッセージを抑制したり、gcc をこれについてより賢くするように誘導するにはどうすればよいでしょうか? -Wconversion フラグは、コード ベースで何千もの警告を生成します。それらすべてを調べる必要がありますか?うーん。

#include <stdio.h>
void
takes_a_float  ( float some_num ) {
    printf("float Hello %f\n", some_num );
}
int
main (int argc, char **argv)  {
    float my_boat = 1.0f;
    takes_a_float (  my_boat );
    exit (0);
}

gcc -Wconversion foo.c
foo.c: In function `main':
foo.c:13: warning: passing arg 1 of `takes_a_float' as `float' rather than `double' due to prototype

 $ gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr   /share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)

編集

John Millikin が指摘したように、-Wconversion フラグは「設計どおり」に機能しています。(私はそれが型変換に関するものだと思っていましたが、それは本当に古い C スタイルのプログラムを ISO 標準の C に変換することに関するものであることがわかりました。くそー。gcc の私のバージョンの gcc 警告ドキュメント ページを読んでもわかりません。希望はありますが、いずれにせよ、私が本当に欲しいのは、次のコードで正しく警告し、誤った警告を出さない他の警告フラグを有効にすることです。

#include <stdio.h>
#include <stdlib.h>


void
takes_a_long  ( long sad_story ) {
    printf("Long %lu\n", sad_story );
}

void
takes_a_float  ( float my_boat ) {
    printf("Float  %f\n", my_boat );
}

int
main (int argc, char **argv)  {

    float   my_boat     = 1.0f;
    long    sad_story   = 1.0L;

    // No warnings wanted
    takes_a_float (my_boat);
    takes_a_long (sad_story);

    // Warnings required
    takes_a_long  (my_boat);
    takes_a_float (sad_story);

    exit (0);
}

編集 2

本当の解決策は、コンパイラをアップグレードすることです。複雑な理由で会社が喜んでやろうとしていることではありません(ため息)。

4

4 に答える 4

3

マンページから(http://lists.apple.com/archives/xcode-users/2008/Jul/msg00720.htmlでも):

-Wコンバージョン

プロトタイプが、プロトタイプがない場合に同じ引数に起こるものとは異なる型変換を引き起こす場合に警告します。これには、固定小数点から浮動小数点への変換、およびその逆の変換、および固定小数点引数の幅または符号を変更する変換が含まれます。ただし、デフォルトの昇格と同じ場合を除きます。

したがって、警告は文書化されているとおりに実行されます。特定の変換を確認したい場合は-Wconversion、単一の実行をオンにして、それをファイルに記録し、long-> floatconversions を検索してみてください。


このオプションは、従来の C を ISO/ANSI C に移植する際に使用することを意図しているようです。

于 2009-04-14T21:44:17.950 に答える
2

情報ページからの推測ですが、試してみました-Wno-traditional-conversionか?

編集:確認しましたが、動作しますが、残念ながら、これは gcc 4.3 以降でのみ動作します。gcc 4.1 のマニュアル ページから、観察された動作は古いバージョンで実行されるはずだったものであり、通常の変換-Wconversionでは警告が表示されないようです。double -> float

于 2009-04-14T21:38:33.067 に答える
2

あなたが探している可能性が最も高いフラグは、XX が (c89|gnu89|c99|gnu99|...) の 1 つである場所-Wallと組み合わせたいと考えているフラグであり、および/またはさらに厄介なペダンティック (またはそれ以上) である可能性があります。あなたの気分に応じて、完全に保持します:)-std=XX-pedantic

ところで、stdlib.h (exit() プロトタイプ用) を含めるのを忘れていました。


#include <stdio.h>
#include <stdlib.h>

void takes_a_float ( float some_num ) {
    printf("float Hello %f\n", some_num );
}

int main (int argc, char **argv)  {
   float my_boat = 1.0;
   takes_a_float (  my_boat );
   exit( 0 );
}

そして私のコンソール出力:


mctaylor@tigger:stackoverflow$ gcc -Wall -pedantic long_float.c -o long_float
mctaylor@tigger:stackoverflow$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
...
gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12) 

-Wall -pedanticを使用すると、きれいで明示的なコードを書くことが強制され、多くの潜在的なばかげた間違いを見つけるのに役立ちます。幸運を。

「警告がありません」というメッセージが表示されるのは、C タイプのプロモーション ルールが原因ではないでしょうか。(K&R The C Programming Language, 2nd ed, section 2.7 - Type Conversionを参照してください)。考えるだけの食べ物です。

これが役立つことを願っています。

追加の資料を追加するために編集されました(次のとおり):

もう 1 つのオプションまたはアプローチは、 splint (Secure Programming Lint) またはGimple Softwareの PC-lint / FlexLint です。これは、疑わしい移植性のない構造にフラグを立てる C ソース コードの静的分析のlint実装です


mctaylor@tigger:stackoverflow$ splint sad_story.c 
Splint 3.1.2 --- 07 May 2008

sad_story.c: (in function takes_a_long)
sad_story.c:5:26: Format argument 1 to printf (%lu) expects unsigned long int
                     gets long int: sad_story
  To ignore signs in type comparisons use +ignoresigns
   sad_story.c:5:20: Corresponding format code
sad_story.c: (in function main)
sad_story.c:21:18: Function takes_a_long expects arg 1 to be long int gets
                      float: my_boat
  To allow all numeric types to match, use +relaxtypes.
sad_story.c:22:19: Function takes_a_float expects arg 1 to be float gets long
                      int: sad_story
sad_story.c:12:15: Parameter argc not used
  A function parameter is not used in the body of the function. If the argument
  is needed for type compatibility or future plans, use /*@unused@*/ in the
  argument declaration. (Use -paramuse to inhibit warning)
sad_story.c:12:28: Parameter argv not used
sad_story.c:4:6: Function exported but not used outside sad_story: takes_a_long
  A declaration is exported, but not used outside this module. Declaration can
  use static qualifier. (Use -exportlocal to inhibit warning)
   sad_story.c:6:1: Definition of takes_a_long
sad_story.c:8:6: Function exported but not used outside sad_story:
                    takes_a_float
   sad_story.c:10:1: Definition of takes_a_float

Finished checking --- 7 code warnings

また、Gimpel のオンライン テストで FlexLint の例を試すこともできます。これは、クリーンできれいな出力です。

于 2009-04-14T23:15:21.977 に答える
0

この警告は表示されません。GCC の最新バージョン (4.3.3) を使用しているためだと思います。

于 2009-04-14T21:54:48.847 に答える