Input from a newbie

Artur Skawina art.08.09 at gmail.com
Mon Apr 9 10:08:33 PDT 2012


On 04/09/12 17:39, Andrej Mitrovic wrote:
> On 4/9/12, Jonas <jonas at lophus.org> wrote:
>> On Saturday, 7 April 2012 at 22:42:19 UTC, Stefan wrote:
>>> printf is a C function which expects 0-terminated strings. D's
>>> strings are variable-length arrays and not zero-terminated.
>>>
>>> Don't use printf. Try using writef instead. Same arguments.
>>
>> http://d.puremagic.com/issues/show_bug.cgi?id=7872
> 
> I don't think the compiler can warn about this. Isn't printf one of
> those unsafe C variadic functions? Someone correct me if I'm wrong.

It is, but arguably this is exactly why it should warn - it's unlikely
that passing a D array to an extern(C) variadic function is really what
the programmer intended. Except of course when he relies on the internal
D array representation - and, as this hack is given as an example on 
dlang.org, issuing a warning is out of the question, w/o special-casing
for printf and parsing the format string...

However, there's no reason why *std.stdio* should expose the raw printf
function - i didn't even realize it did until now...
It either shouldn't be available via std.stdio at all, or something
like this wrapper should be added there, to catch the inevitable mistakes:

int printf(string F=__FILE__, int L=__LINE__, A...)(A args) {
   import std.typetuple;
   import std.string;
   import std.c.stdio;
   alias ReplaceAll!(immutable(char)[], char*, A) CA;
   CA cargs;
   foreach (i, arg; args) {
      static if (is(typeof(arg):const(char)[])) {
         pragma(msg, F ~ ":" ~ L.stringof ~
           " Warning: C function printf expects zero-terminated (char*), not D array");
         cargs[i] = cast(char*)toStringz(arg);
      }
      else
         cargs[i] = arg;
   }
   return std.c.stdio.printf(cargs);
}

The raw printf can then still be used via std.c.stdio or core.stdc.stdio, 
but a program using just std.stdio will print a warning instead of segfaulting.
Parsing the format string to avoid the warnings for the "%.*s" case could be
done too, i guess.


On 04/09/12 17:50, Jonas H. wrote:
> The GCC C compiler proves you wrong :) They have warnings. I guess it's a hack (because printf really doesn't belong into the compiler) but that doesn't matter.  What matters is user-friendliness.

D doesn't even need compiler support for this - it can be done completely
inside the library.

artur


More information about the Digitalmars-d-learn mailing list