www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - writefln format specifier for pointers?

reply Geoff Hickey <Geoff_member pathlink.com> writes:
I feel like I'm missing something obvious, but there doesn't seem to be a format
specifier that will cause writef to display the value of a pointer. %x, %d, and
%s all result in an exception being thrown ("std.format", which is probably
coming from format.d line 698.)

Obviously I can cast the pointer to an integral type and use %x, but no one
likes unnecessary casts.

Is there a better option, or is this a missing format specifier?

- Geoff
Dec 01 2004
next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <coll26$10oi$1 digitaldaemon.com>, Geoff Hickey says...
I feel like I'm missing something obvious, but there doesn't seem to be a format
specifier that will cause writef to display the value of a pointer. %x, %d, and
%s all result in an exception being thrown ("std.format", which is probably
coming from format.d line 698.)

Obviously I can cast the pointer to an integral type and use %x, but no one
likes unnecessary casts.

Is there a better option, or is this a missing format specifier?
Try %p Sean
Dec 01 2004
parent Geoff Hickey <Geoff_member pathlink.com> writes:
%p works with printf, but not writefln.

- Geoff

In article <colo5r$14of$1 digitaldaemon.com>, Sean Kelly says...
In article <coll26$10oi$1 digitaldaemon.com>, Geoff Hickey says...
I feel like I'm missing something obvious, but there doesn't seem to be a format
specifier that will cause writef to display the value of a pointer. %x, %d, and
%s all result in an exception being thrown ("std.format", which is probably
coming from format.d line 698.)

Obviously I can cast the pointer to an integral type and use %x, but no one
likes unnecessary casts.

Is there a better option, or is this a missing format specifier?
Try %p Sean
Dec 01 2004
prev sibling next sibling parent reply pragma <pragma_member pathlink.com> writes:
Just shooting from the hip here, but have you tried "%o"?


In article <coll26$10oi$1 digitaldaemon.com>, Geoff Hickey says...
I feel like I'm missing something obvious, but there doesn't seem to be a format
specifier that will cause writef to display the value of a pointer. %x, %d, and
%s all result in an exception being thrown ("std.format", which is probably
coming from format.d line 698.)

Obviously I can cast the pointer to an integral type and use %x, but no one
likes unnecessary casts.

Is there a better option, or is this a missing format specifier?

- Geoff
- pragma (ericanderton at yahoo)
Dec 02 2004
parent reply Geoff Hickey <Geoff_member pathlink.com> writes:
In article <convmv$1kas$1 digitaldaemon.com>, pragma says...
Just shooting from the hip here, but have you tried "%o"?
I hadn't, so I did, but it didn't work either. Here's a snippet for anyone who wants to see the problem: int main() { int* p = cast(int*)0xf0d00000; writefln( "ptr: %o", p ); return 0; }
Dec 02 2004
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 2 Dec 2004 21:45:32 +0000 (UTC), Geoff Hickey  
<Geoff_member pathlink.com> wrote:
 In article <convmv$1kas$1 digitaldaemon.com>, pragma says...
 Just shooting from the hip here, but have you tried "%o"?
I hadn't, so I did, but it didn't work either. Here's a snippet for anyone who wants to see the problem: int main() { int* p = cast(int*)0xf0d00000; writefln( "ptr: %o", p ); return 0; }
I did a little hacking.. I took the contents of std.format and std.stdio and placed them in a .d file with a main containing only "writefln(cast(void*)0xf0d00000);" this is so I can step into the writef call in MSVC's debugger. Doing so shows it fails in doFormat on the line: if (ti.classinfo.name.length < 10) goto Lerror; ti.classinfo.name is "TypeInfo" and the length is 8, it seems there is no typeinfo for a void *? Using writefln("%p",cast(void*)0xf0d00000); causes it to get an array bounds error?! later at these lines: ti = arguments[j++]; m = cast(Mangle)ti.classinfo.name[9]; I think the above code should read ti = arguments[j++]; if (ti.classinfo.name.length < 10) goto Lerror; m = cast(Mangle)ti.classinfo.name[9]; or something similar as at this point ti.classinfo.name is "TypeInfo" and the length is 8 as it was in my first case. It appears to me it's not correctly identifying the type you're trying to print, and/or it has not TypeInfo and does not print. Something like that anyway. Regan
Dec 02 2004
parent reply Geoff Hickey <ardri comcast.net> writes:
Regan Heath wrote:
 On Thu, 2 Dec 2004 21:45:32 +0000 (UTC), Geoff Hickey  
 <Geoff_member pathlink.com> wrote:
 
 In article <convmv$1kas$1 digitaldaemon.com>, pragma says...

 Just shooting from the hip here, but have you tried "%o"?
I hadn't, so I did, but it didn't work either. Here's a snippet for anyone who wants to see the problem: int main() { int* p = cast(int*)0xf0d00000; writefln( "ptr: %o", p ); return 0; }
I did a little hacking.. I took the contents of std.format and std.stdio and placed them in a .d file with a main containing only "writefln(cast(void*)0xf0d00000);" this is so I can step into the writef call in MSVC's debugger.
I had to put this down for awhile, but I dug back into it tonight, following the same path you took. It seems that the problem is with the TypeInfo instance for pointer types. In particular, I went back to this place (format.d line 528 in dmd v.109):
 Doing so shows it fails in doFormat on the line:
 
 if (ti.classinfo.name.length < 10)
         goto Lerror;
 
 ti.classinfo.name is "TypeInfo" and the length is 8, it seems there is
 no  typeinfo for a void *?
and changed it to this (this is *not* a fix, just hacking in a default): if (ti.classinfo.name.length < 10) { ti.classinfo.name ~= "_P"; } since by my shallow reading of the dmd code the TypeInfo.classinfo.name string for a pointer should be TypeInfo_P. When I did this, the following code worked: int main() { int* p = cast(int*)0xf0d00000; try { writefln( p ); //writefln( "%p", p ); writefln( "%x", p ); writefln( "%d", p ); writefln( "%o", p ); } catch { writefln( "Blew up!" ); } return 0; } It displays: f0d00000 // no format string f0d00000 // %x f0d00000 // %d ??? I was expecting decimal output here, not hex? 36064000000 // %o octal (correct) It doesn't matter what the pointer type is pointing *to*, by the way, void*, int*, struct* all give the same result (I haven't tried a class instance pointer). So, I think that there's something wrong with the TypeInfo instances for pointers. If I've missed something (quite possible) please let me know, otherwise if everyone agrees I'll post this to D.bugs? Thanks Regan and everyone else who replied for taking the time. - Geoff Hickey
Dec 08 2004
parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 09 Dec 2004 01:23:16 -0500, Geoff Hickey <ardri comcast.net> wrote:
 Regan Heath wrote:
 On Thu, 2 Dec 2004 21:45:32 +0000 (UTC), Geoff Hickey   
 <Geoff_member pathlink.com> wrote:

 In article <convmv$1kas$1 digitaldaemon.com>, pragma says...

 Just shooting from the hip here, but have you tried "%o"?
I hadn't, so I did, but it didn't work either. Here's a snippet for anyone who wants to see the problem: int main() { int* p = cast(int*)0xf0d00000; writefln( "ptr: %o", p ); return 0; }
I did a little hacking.. I took the contents of std.format and std.stdio and placed them in a .d file with a main containing only "writefln(cast(void*)0xf0d00000);" this is so I can step into the writef call in MSVC's debugger.
I had to put this down for awhile, but I dug back into it tonight, following the same path you took. It seems that the problem is with the TypeInfo instance for pointer types. In particular, I went back to this place (format.d line 528 in dmd v.109):
 Doing so shows it fails in doFormat on the line:
  if (ti.classinfo.name.length < 10)
         goto Lerror;
> ti.classinfo.name is "TypeInfo" and the length is 8, it seems there is > no typeinfo for a void *? > and changed it to this (this is *not* a fix, just hacking in a default): if (ti.classinfo.name.length < 10) { ti.classinfo.name ~= "_P"; } since by my shallow reading of the dmd code the TypeInfo.classinfo.name string for a pointer should be TypeInfo_P. When I did this, the following code worked: int main() { int* p = cast(int*)0xf0d00000; try { writefln( p ); //writefln( "%p", p ); writefln( "%x", p ); writefln( "%d", p ); writefln( "%o", p ); } catch { writefln( "Blew up!" ); } return 0; } It displays: f0d00000 // no format string f0d00000 // %x f0d00000 // %d ??? I was expecting decimal output here, not hex? 36064000000 // %o octal (correct) It doesn't matter what the pointer type is pointing *to*, by the way, void*, int*, struct* all give the same result (I haven't tried a class instance pointer). So, I think that there's something wrong with the TypeInfo instances for pointers. If I've missed something (quite possible) please let me know, otherwise if everyone agrees I'll post this to D.bugs? Thanks Regan and everyone else who replied for taking the time.
You're welcome, I think we should post this to the bugs NG so Walter see's it. Regan
Dec 09 2004
prev sibling parent Tyro <ridimz_at yahoo.dot.com> writes:
Geoff Hickey wrote:
 I feel like I'm missing something obvious, but there doesn't seem to be a
format
 specifier that will cause writef to display the value of a pointer. %x, %d, and
 %s all result in an exception being thrown ("std.format", which is probably
 coming from format.d line 698.)
 
 Obviously I can cast the pointer to an integral type and use %x, but no one
 likes unnecessary casts.
 
 Is there a better option, or is this a missing format specifier?
 
 - Geoff
 
 
A workaround maybe? void main() { uint ui = cast(int*)0xf0d00000; uint* pui = &ui; writefln("%x",*pui); writefln(*pui); writefln("%d",*pui); writefln("%o",*pui); writefln("%b",*pui); }
Dec 02 2004