lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

I just found a bug in an embedded port of lua which didn't support
sprintf().  Specifically, the work-around:

    #define sprintf(s,fmt,...)  snprintf(s, sizeof(s), fmt, __VA_ARGS__)

is broken.  Consider correct code such as:

    char *b = ...; sprintf(b, "%d", 1);

found in lstrlib.c.

This, however, begs the question: should lua switch to snprintf()?

First, I don't think anyone will dispute that snprintf() is more
robust than sprintf().  Rather, the problem is with portability.
While snprintf() was formalized in c99, and almost all the C compilers
have been supporting it since forever, there's been one holdout -
Microsoft - they have had a somewhat recalcitrant attitude towards C
standards compliance and, consequently, snprintf wasn't an option
(Microsoft does have sprintf_s()  and _snprintf() but they have
different semantics).
http://en.cppreference.com/w/c/io/fprintf
https://msdn.microsoft.com/en-us/library/2ts7cx93%28v=vs.120%29.aspx

However, recently we've been seeing something of a shift in
Microsoft's attitude. Specifically Visual Studio 14/15 should support
things like snprintf:
http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp.aspx

So I'd like to float the idea of adopting snprintf(), for instance:

- just assume snprintf (which would require a very recent Microsoft C compiler)

- define Lsnprintf() as snprintf() and use that, except on old windows
systems which can wrap _snprintf() and deal with the different
semantics

- define Lsnrintf() as snprintf() and use that, except on windows
where it is re-defined as sprintf() (ignore the length parameter);
this means things are no worse than what we have now

Andrew