On 04/09/12 17:39, Andrej Mitrovic wrote: > On 4/9/12, Jonas <jo...@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