NSLog(…) improper format specifier affects other variables?

﹥>﹥吖頭↗ 提交于 2019-12-06 09:42:59

You just messed up memory alignment on your stack. I assume than you use newest Apple product with x86 processor. Taking these assumptions into account your stack looks like that in both situations:

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

In first situation you put on stack 8 bytes and then 4 bytes. And than NSLog is instructed to take back from stack 12 bytes (8 bytes for %lld and 4 bytes for %@).

In second situation you instruct NSLog to first take 4 bytes (%d). Since your variable is 8 bytes long and holds really small number its upper 4 bytes will be 0. Then when NSLog will try to print text it will take nil from stack.

Since sending message to nil is valid in Obj-C NSLog will just send description: to nil get probably nothing and then print (null).

In the end since Objective-C is just C with additions, caller cleans up whole this mess.

How varargs are implemented is system-dependent. But what is likely happening is that the arguments are stored consecutivelyly in a buffer, even though the arguments may be different sizes. So the first 8 bytes (assuming that's the size of a long long int) of the arguments is the long long int, and the next 4 bytes (assuming that's the size of a pointer on your system) is the NSString pointer.

Then when you tell the function that it expects an int and then a pointer, it expect the first 4 bytes to be the int (assuming that's the size of an int) and the next 4 bytes to be the pointer. Because of the particular endianness and arrangement of arguments on your system, the first 4 bytes of the long long int happens to be the least significant bytes of your number, so it prints 123. Then for the object pointer, it reads the next 4 bytes, which in this case is the most significant bytes of your number, which is all 0, so that gets interpreted as a nil pointer. The actual pointer never gets read.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!