3

変更可能なセットが別のセットと正しく交差しない理由を見つけるのに少し時間を費やしました。

    [someMutableSet intersectsSet:anotherSet]; // not the best idea

もちろん、正しい構文はであり、上記の行は別のことを意味します。これは型[someMutableSet intersectSet:anotherSet]の戻り値を持つメソッド呼び出しです。BOOL

オプションを有効にしているので-Wall -Wextra、これは警告としてキャッチされているはずです。しかし、それはキャッチされませんでした。私は試してさらに調査しましtypesNSMutableSet

    (void)[types intersectsSet:types]; // -> no warning, this is expected

    (BOOL)[types intersectsSet:types]; // (1) -> warning, this is expected

そして、繰り返しますが、これを行うと:

    [types intersectsSet:types];  // (2) -> no warning, UNEXPECTED

- (BOOL)intersectsSet:(NSSet *)otherSet;(1) と (2) が同等であると予想されるようにメソッドが定義されているとしても、警告はありません。悪質なコンパイル ツールは (1) を (2) よりも危険な性質のものと見なしているのかもしれませんが、なぜそれが警告に影響するのでしょうか?

では、(2) で (1) と同じ警告をコンパイラに生成させるにはどうすればよいでしょうか?

4

1 に答える 1

2

コンパイラでのこの動作は、意図的 (かつ合理的) に思われます。

メソッドが暗黙的に破棄される戻り値を持つ (つまり、void キャストがない) すべての ObjC メッセージ送信式に対して警告が発行された場合、-Wunused-valueそれ自体が役に立たなくなるほど「おしゃべり」になります。言い換えれば、人々は既存のプロジェクトに対して非常に多くの警告を受け取り、そのようなケースすべてに(void)キャストで注釈を付けるのではなく、単純に警告をオフにするでしょう。

戻り値がキャストされた場合に警告BOOL発行されるという事実は、驚くべきことであり、理にかなっています。コンパイラーがプログラマーが実際に戻り値に関心があると想定することは合理的です (そうでなければ、キャスト?)

cfe-dev メーリング リストの Clang 開発コミュニティは、この背後にある考え方についてより多くの情報を提供できるかもしれません。

一般的に必要な動作を強制する方法はわかりませんが、独自のコードのインターフェイスについてはwarn_unused_result、ObjC メソッド (または C 関数) 宣言で属性を使用してこの警告を強制できます。

@interface MyClass : NSObject
- (int) myReturnValueMustNotBeIgnored __attribute__((warn_unused_result));
@end
于 2014-05-12T11:43:57.243 に答える