NSLog(…)不適切なフォーマット指定子は他の変数に影響しますか?

StackOverflow https://stackoverflow.com/questions/1229212

質問

NS
NSString *text = @"abc";
long long num = 123;
NSLog(@"num=%lld, text=%@",num,text); //(A)
NSLog(@"num=%d, text=%@",num,text); //(B)

行(A)は期待される" num = 123、text = abc"を印刷しますが、行(B)は" num = 123、text = (null)"を印刷します。

明らかに、%d long long を印刷するのは間違いですが、誰かが text を次のように印刷する理由を説明できますnull?

役に立ちましたか?

解決

スタックのメモリの配置が台無しになりました。 x86プロセッサを搭載した最新のApple製品を使用していることを前提としています。これらの仮定を考慮に入れると、スタックは両方の状況で次のようになります。

   |      stack          | first | second |
   +---------------------+-------+--------+
   |        123          |       |  %d    |
   +---------------------+ %lld  +--------+
   |         0           |       |  %@    |
   +---------------------+-------+--------+
   |   pointer to text   | %@    |ignored |
   +---------------------+-------+--------+  

最初の状況では、スタックに8バイト、次に4バイトをスタックします。 NSLogはスタックから12バイト(%lld の場合は8バイト、%@ の場合は4バイト)を返すように指示されています。

2番目の状況では、NSLogに最初に4バイト(%d )を使用するよう指示します。変数の長さは8バイトで、小さい数値を保持するため、その上位4バイトは0になります。NSLogがテキストを印刷しようとすると、スタックから nil が使用されます。

Obj-Cでは nil へのメッセージ送信が有効なので、NSLogは description: nil に送信するだけで、おそらく何も取得せずに印刷します( null)。

Objective-Cは追加されたCであるため、呼び出し側はこの混乱をすべてクリーンアップします。

他のヒント

可変引数の実装方法はシステムに依存します。ただし、引数のサイズが異なる場合でも、引数はバッファに連続して格納される可能性があります。そのため、引数の最初の8バイト( long long int のサイズであると仮定)は long long int であり、次の4バイトは(それがシステム上のポインター)は NSString ポインターです。

次に、関数に int を期待し、次にポインターを期待すると、最初の4バイトが int であると期待します(サイズが int )および次の4バイトがポインターになります。システム上の特定のエンディアンと引数の配置のため、 long long int の最初の4バイトはたまたま数字の最下位バイトなので、123を出力します。 、次の4バイトを読み取ります。この場合、これは数値の最上位バイトであり、すべて0であるため、 nil ポインターとして解釈されます。実際のポインターは読み取られません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top