iOS 用の Objective-C で開発しているときにこの問題に遭遇しましたが、これは Mac OS X/iOS リンカーを使用するすべての C/C++/Objective-C コードに当てはまるはずです。解決策は別の質問でカバーされていますが、私はその理由に興味があります。
定数を定義するライブラリへのリンクを使用しているとしましょう。ヘッダー ファイルには、次のような宣言があります。
extern char * const BrandNewIdentifier;
アプリケーションをコンパイルして、その定数が定義されていない以前のバージョンのライブラリを使用してシステムで実行したいので、安全のために定義されているとは想定していません。
ライブラリの最新バージョンでのみ定義されている関数がある場合は、次のようにします。
if (BrandNewFunc) {
BrandNewFunc("foobar", 42);
} else {
printf("Your system does not support some thing.");
}
関数コードのアドレスを含む代わりに、BrandNewFunc
NULL に評価されます。定数は同じように動作すると思いますが、同じパターンを試すと、チェックの実行中にアプリが停止します (iOS では EXC_BAD_ACCESS がスローされます)。具体的には:
if (BrandNewIdentifier) ... // blows up here
代わりに機能するのは、識別子のアドレスをチェックすることです:
if (&BrandNewIdentifier) {
printf("You got it!");
}
ロジックはわかりますBrandNewIdentifier
。値がないため、アクセスは失敗するはずです。しかし、なぜその構文は次の場合に機能するのBrandNewFunc
でしょうか? そのアドレスも確認する必要があるのではないでしょうか? それとも、実際には一貫しており、見落としているものがありますか?