Token newbie 64-bit question

nick rothwell | project cassiel's icon

I'm looking at simplemax.c. The new function does this:

object_post((t_object *)x, "a new %s object was instantiated: 0x%X", s->s_name, x);

Since the %X isn't qualified, isn't this wrong for 64-bit pointers?

I get a slightly different (and possibly correct) answer for:

object_post((t_object *)x, "a new %s object was instantiated: 0x%llX", s->s_name, x);

although that's not very portable. The C99 standard is something like

object_post((t_object *)x, "a new %s object was instantiated: 0x" PRIxPTR, s->s_name, x);

but object_post doesn't seem to work with that (I get 1x printed for the pointer value).

Is there a sanctified way to do this? (I'll try the standard sprintf to see what that produces.)

This is OS X/Xcode 4, btw.

Luigi Castelli's icon

On my platform [ MacOS 10.8.3 running Max 6.1.1 (64-bit) ] this seems to work and should also be portable.

object_post((t_object *)x, "a new %s object was instantiated: %p", s->s_name, x);

The only problem I see is that there's no really good way to determine the maximum length of the string produced by "%p". However, for most uses it should be fine.

Let me know if it works for you...

- Luigi

nick rothwell | project cassiel's icon

Ah, %p. I've been using Java for too long...

For what it's worth, here's my test code:

object_post((t_object *)x, "object via %%X:      %X", x);
object_post((t_object *)x, "object via %%llX:    %llX", x);
object_post((t_object *)x, "object via %%p:      %p", x);
object_post((t_object *)x, "object via PRIxPTR: %" PRIxPTR, x);

The 32-bit output is:

simplemax: object via %X:      BE944A8
simplemax: object via %llX:    C00670BE944A8
simplemax: object via %p:      0xbe944a8
simplemax: object via PRIxPTR: be944a8

The 64-bit output is:

simplemax: object via %X:      C4A2578
simplemax: object via %llX:    10C4A2578
simplemax: object via %p:      0x10c4a2578
simplemax: object via PRIxPTR: 10c4a2578

(Ignore the PRIxPTR complaint earlier: I woz doing it wrong.)

PRIxPTR appears to be "lx", which must translate to 8-bytes in a 64-bit env.

In 64 env, %X appears to deliver the low-order long, and (after more experimentation) doesn't appear to corrupt the stack. (I don't immediately understand why not, unless it's some register allocation business. I've not done machine code for decades.)

In 32 env, %llX corrupts the stack (so it's still 64 bits); %lX works fine (so must mean 32 bits here).

So for 64 bits the %X of the example code appears benign, but the value is wrong. Tim: could you consider this a manual GitHub pull request to make this %p or "%" PRIxPTR?

nick rothwell | project cassiel's icon

While I'm here: turning on -Wall in Xcode gives me Unknown Pragma in

#ifdef MAC_VERSION
#ifndef powerc
#pragma d0_pointers on
#endif
...

(in ext_prefix.h.) It seems that -Wall is a nice one to have, and it would be nice if the build were still clean.