March 14, 2005
AEon wrote:

> How come printf does not take __FILE__ well?

You need to use either "%.*s" or toStringz() :

> printf("   File:		%.*s\n",__FILE__);

> printf("   File:		%s\n",std.string.toStringz(__FILE__));

Or:

> writefln("   File:      %s",__FILE__);

Either is fine, but writef is probably easiest ?

Strings in D are not zero-terminated, unless they
are string literals (""), and that was what bit you.

--anders
March 15, 2005
In article <opsnngzocg23k2f5@nrage.netwin.co.nz>, Regan Heath says...

>> // -> File:                Error: Access Violation
>> printf("   File:		%s\n",__FILE__);

>I assume it's because __FILE__ is a D string, and not a null-terminated C string.

Right, I had no real idea what type __FILE__ was.

Strangely:

printf("Line: %.*s\n",__LINE__);

yields: "Line: (null)", whereas:

writefln("Line: %s",__LINE__);

yields: "Line: 80", some valid number.

Did I stumble on some known bug? Or am I missing some special case?


anders,

> printf(  "File:  %.*s\n", __FILE__ );
> printf(  "File:  %s\n",   std.string.toStringz(__FILE__) );
> writefln("File:  %s",     __FILE__ );

thanx for the explicit examples, those really help, i.e. how to force a D string to be a "C string".

I had not fully understood the naming of writefln, the "ln" saving you a \n. Neat!

This forum is great, should get me D coding in a jiffy :)

AEon
March 15, 2005
On Tue, 15 Mar 2005 00:00:56 +0000 (UTC), AEon <AEon_member@pathlink.com> wrote:
> In article <opsnngzocg23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>
>>> // -> File:                Error: Access Violation
>>> printf("   File:		%s\n",__FILE__);
>
>> I assume it's because __FILE__ is a D string, and not a null-terminated C
>> string.
>
> Right, I had no real idea what type __FILE__ was.
>
> Strangely:
>
> printf("Line: %.*s\n",__LINE__);
>
> yields: "Line: (null)", whereas:
>
> writefln("Line: %s",__LINE__);
>
> yields: "Line: 80", some valid number.
>
> Did I stumble on some known bug? Or am I missing some special case?

__LINE__ is not a char[] it is an integer type perhaps 'int' eg.

printf("%d\n",__LINE__);

I am not sure why:

writefln("Line: %s",__LINE__);

works, writefln must be doing something clever.

Regan
March 15, 2005
On Tue, 15 Mar 2005 13:12:24 +1300, Regan Heath wrote:

> On Tue, 15 Mar 2005 00:00:56 +0000 (UTC), AEon <AEon_member@pathlink.com> wrote:
>> In article <opsnngzocg23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>>
>>>> // -> File:                Error: Access Violation
>>>> printf("   File:		%s\n",__FILE__);
>>
>>> I assume it's because __FILE__ is a D string, and not a null-terminated
>>> C
>>> string.
>>
>> Right, I had no real idea what type __FILE__ was.
>>
>> Strangely:
>>
>> printf("Line: %.*s\n",__LINE__);
>>
>> yields: "Line: (null)", whereas:
>>
>> writefln("Line: %s",__LINE__);
>>
>> yields: "Line: 80", some valid number.
>>
>> Did I stumble on some known bug? Or am I missing some special case?
> 
> __LINE__ is not a char[] it is an integer type perhaps 'int' eg.
> 
> printf("%d\n",__LINE__);
> 
> I am not sure why:
> 
> writefln("Line: %s",__LINE__);
> 
> works, writefln must be doing something clever.

It does. With printf, the coder has to ensure that the formatting codes match up with the data type passed for each respective argument. However, writef knows the data types of the arguments and does things accordingly.

For example, you can also write ...

  writefln("Line: ", __LINE__);

or

  writefln("Line: %d", __LINE__);

to get the same results.

-- 
Derek
Melbourne, Australia
15/03/2005 11:28:43 AM
March 15, 2005
Regan Heath wrote:
> On Tue, 15 Mar 2005 00:00:56 +0000 (UTC), AEon <AEon_member@pathlink.com>  wrote:
> 
>> In article <opsnngzocg23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>>
>>>> // -> File:                Error: Access Violation
>>>> printf("   File:        %s\n",__FILE__);
>>
>>
>>> I assume it's because __FILE__ is a D string, and not a null-terminated  C
>>> string.
>>
>>
>> Right, I had no real idea what type __FILE__ was.
>>
>> Strangely:
>>
>> printf("Line: %.*s\n",__LINE__);
>>
>> yields: "Line: (null)", whereas:
>>
>> writefln("Line: %s",__LINE__);
>>
>> yields: "Line: 80", some valid number.
>>
>> Did I stumble on some known bug? Or am I missing some special case?
> 
> 
> __LINE__ is not a char[] it is an integer type perhaps 'int' eg.
> 
> printf("%d\n",__LINE__);
> 
> I am not sure why:
> 
> writefln("Line: %s",__LINE__);
> 
> works, writefln must be doing something clever.
> 
> Regan


Perhaps because:

writefln("Line: ", __LINE__);

works... writefln knows how to deal with the types of the passed args without specifying the string formatting (only if sequential printing or the args is desired, though).  The %s is probably ignored in your sample because the type doesn't match?

-JJR
March 15, 2005
"John Reimer" <brk_6502@yahoo.com> wrote in message news:d15ahi$2u6f$1@digitaldaemon.com...
> The %s is probably ignored in your sample
> because the type doesn't match?

No, it isn't ignored. %s means "format the argument as a string, and insert it here." All argument types writefln knows about can be formatted as strings (after all, that's the whole point of it!).

For example,
    writefln("hello %s baby", __LINE__);
writes:
    hello 47 baby
assuming it is on line 47.

%d, %u, %x are there so one can format integral types into signed integers, unsigned integers, or hex strings.

The format specifiers in printf specify both type and format. For writef, they only specify the format. The type is already known to writef.

An article on this was in the January Dr. Dobb's.


March 15, 2005
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d14saa$2fie$1@digitaldaemon.com...
> > Hopefully those would be covered in the documentation ?
>
> Programmers (rrreal ones) do not read this stuff anyway.
>
> BTW: Original question starts from "How to..."  so is a first candidate
for
> howto.

Feature requests always start out with "it would be nice if..." <g>.


March 15, 2005
Walter wrote:
> "John Reimer" <brk_6502@yahoo.com> wrote in message
> news:d15ahi$2u6f$1@digitaldaemon.com...
> 
>>The %s is probably ignored in your sample
>>because the type doesn't match?
> 
> 
> No, it isn't ignored. %s means "format the argument as a string, and insert
> it here." All argument types writefln knows about can be formatted as
> strings (after all, that's the whole point of it!).
> 
> For example,
>     writefln("hello %s baby", __LINE__);
> writes:
>     hello 47 baby
> assuming it is on line 47.
> 
> %d, %u, %x are there so one can format integral types into signed integers,
> unsigned integers, or hex strings.
> 
> The format specifiers in printf specify both type and format. For writef,
> they only specify the format. The type is already known to writef.
> 
> An article on this was in the January Dr. Dobb's.
> 
> 

Thanks for the clarification.  That makes much more sense.
March 15, 2005
Derek Parnell wrote:

>For example, you can also write ...
>  writefln("Line: ", __LINE__);
>or
>  writefln("Line: %d", __LINE__);
>to get the same results.

Indeed. Both work, you can even do this (as was pointed out, writefln is *very* flexible), though the formatting would be less than optimal:

// Line: test.d 96Mar 15 200511:17:12Tue Mar 15 11:17:12 2005 writefln("Line: %d ", __FILE__,__LINE__,__DATE__,__TIME__,__TIMESTAMP__);

// Line: test.d97Mar 15 200511:17:12Tue Mar 15 11:17:12 2005 writefln("Line: ", __FILE__,__LINE__,__DATE__,__TIME__,__TIMESTAMP__);


I did a full search in the dmd\ development tree for "__TIMESTAMP__", other than in the dmd, and dmd.exe files, the only source related mention of the latter is in

E:\d\dmd\src\dmd\idgen.c

struct Msgtable
{
char *ident;	// name to use in DMD source
char *name;	// name in D executable
};

Msgtable msgtable[] =
{
{ "LINE", "__LINE__" },
{ "FILE", "__FILE__" },
{ "DATE", "__DATE__" },
{ "TIME", "__TIME__" },
{ "TIMESTAMP", "__TIMESTAMP__" },
..
}

Would there have been any way to look up what type "__LINE__" is for printf? I had assumed that simply all those __ vars are strings (as we found out D Strings to be exact)?


PS: Any chance to fix this forum to actually respect indentations, to make the reading of source samples easier to read?

AEon
March 15, 2005
AEon wrote:

> Would there have been any way to look up what type "__LINE__" is for printf? I
> had assumed that simply all those __ vars are strings (as we found out D Strings
> to be exact)?

Sortof... This program:

> import std.stdio;
> void main()
> {
>   writefln("__FILE__ ", typeid(typeof(__FILE__)));
>   writefln("__LINE__ ", typeid(typeof(__LINE__)));
>   writefln("__DATE__ ", typeid(typeof(__DATE__)));
>   writefln("__TIME__ ", typeid(typeof(__TIME__)));
> }

*Should* print the types, but:

__FILE__ TypeInfo
__LINE__ long
__DATE__ TypeInfo
__TIME__ TypeInfo

It seems broken for char[]... ?

--anders