2012-11-19 25 views
22

廃止予定の警告を実装する1つの方法は、廃止予定のコンテキストから呼び出している場合を除いて、廃止された関数の呼び出しに対して警告を出すことです。このようにして、レガシーコードは、ノイズにしか掛からない警告を出さずにレガシーコードを呼び出すことができます。GCCで推奨されなくなった関数で廃止予定の警告を取り除くにはどうすればよいですか?

これは合理的な考え方であり、OS XのGCC 4.2(1)およびClang 4.0(2)とUbuntuのClang 3.0(3)の実装にも反映されています。

  • (1):i686の-りんごdarwin11-LLVM-G ++ - 4.2(GCC)4.2.1(アップル社に基づきが5658を構築)(LLVM 2336.11.00を構築)
  • (2): LLVM 3.0ベースのUbuntu clangバージョン3.0-6ubuntu3(tags/RELEASE_30/final)
  • (3):LLVM 3.0に基づいて、
  • (3)タグ:Apple clangバージョン4.0(タグ/ Apple/clang-421.0.57)

しかし、私がUbuntuでGCC 4.6(4)でコンパイルすると、deprecatのすべての呼び出しで廃止予定の警告が表示されますコンテキストとは関係なく、これは機能の回帰ですか?他の動作をさせるために使用できるコンパイラオプションはありますか?

  • (4):G ++(Ubuntuの/リナロ4.6.3-1ubuntu5)4.6.3

プログラム例:GCC 4.2から

int __attribute__((deprecated)) a() { 
    return 10; 
} 

int __attribute__((deprecated)) b() { 
    return a() * 2; //< I want to get rid of warnings from this line 
} 

int main() { 
    return b(); //< I expect a warning on this line only 
} 

出力(はい、私は同じ警告を2回受け取りますが、私はそれについて気にしません):

main.cpp: In function ‘int main()’: 
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5) 
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5) 
GCC 4.6から

出力:

main.cpp: In function 'int b()': 
main.cpp:6:9: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations] 
main.cpp:6:11: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations] 
main.cpp: In function 'int main()': 
main.cpp:10:9: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations] 
main.cpp:10:11: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations] 

がどのように私はGCC 4.6を説得することができ、それは私のGCC 4.2と同じ出力を与えるべきだと?

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
int __attribute__((deprecated)) b() { 
    return a() * 2; //< I want to get rid of warnings from this line 
} 
#pragma GCC diagnostic pop 

注:GCC 4.6以降でのみ動作

+0

これは、FSF GCCではまったく機能しない可能性があります。あなたが見ている4.2の動作は、GCCへのAppleパッチです。確認のためにFSF GCC 4.2をどこにインストールしてもらえますか? – hvd

+0

@hvdあなたが正しいです。私はそのテストを見たいですが、私は4.2を手にしていません:/ –

答えて

11

GCC 4.2で見られる動作は、Apple固有のGCCパッチが原因です。 FSF GCC 4.2.4はaの使用について警告します。(GPLv2の下で、以降使用可能)

--- a/gcc/toplev.c 
+++ b/gcc/toplev.c 
@@ -902,6 +902,9 @@ warn_deprecated_use (tree node) 
    if (node == 0 || !warn_deprecated_decl) 
    return; 

+ if (current_function_decl && TREE_DEPRECATED (current_function_decl)) 
+ return; 
+ 
    if (DECL_P (node)) 
    { 
     expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node)); 

あなたはGCCの新しいバージョン(おそらく変更なしにこのパッチを適応することを望むかもしれない:AppleのGCCはFSF GCCがないことを持っていることを特定のビットおそらく大きな変更が必要です)、このパッチが適用されたソースからGCCをビルドします。あるいは、これをFSF GCC bugzillaの機能要求として報告するかもしれません。

+0

ニート!それはかなり良い答えです。私はこれを機能要求にするつもりだと思う。あなたはdiffをどこで見つけましたか? –

+0

FSFソースをダウンロードし、Appleのソースをダウンロードして、両方を並べて展開し、再帰差分を実行し、結果で「非推奨」を検索し、余りにも多くの結果がないことを願ってください:) – hvd

+0

Hehe、それを手に入れました。私はそれのための時間をスケジュールする必要があります... :)ありがとう! –

26

-Wno-deprecatedは、この問題を解決するのに役立ちます

+10

これはOPが求めているものではありません。 – OmnipotentEntity

+1

@OmnipotentEntity、どうしてですか?レガシーコードを '-Wno-deprecated'と新しいコードなしでコンパイルします。 – Lol4t0

+4

あなたの声明は間違いありませんが、これは私が求めているものではありません。 GCC 4.2が提供する非推奨の警告が欲しい。 –

24

のgcc 4.6追加の診断プラグマをすべて廃止予定の警告を削除します。 pushpopは4.6拡張です。 gcc 4.5では、#pragma GCC diagnostic pushpopは無視されます(警告付き)。無視されないものは#pragma GCC diagnostic ignored "-Wdeprecated-declarations"ですが、これはファイルの最後まで有効です。

+1

+1 - これは、GCCにパッチを当てたくない、あるいはパッチを当てたくない人にとって、本当に良い解決策です。 – Riot

1

同じ問題が発生しました。出てきた解決策は次のとおりです

typedef OLD_A_NOT_TO_BE_USED a __attribute__((deprecated)); 

int OLD_A_NOT_TO_BE_USED() { 
    return 10; 
} 

int __attribute__((deprecated)) b() { 
    return OLD_A_NOT_TO_BE_USED() * 2; //< I want to get rid of warnings from this line 
} 

int main() { 
    return b(); //< I expect a warning on this line only 
} 

だから私のクラスの名前をOLD_A_NOT_TO_BE_USEDクラスに変更するだけです。私はリターンb()でのみ警告を得る。誰かがaを使用していた場合でも、推奨されない警告が表示されます。

関連する問題