views:

39

answers:

2

I am writing a C program that is expected to be compiled with all major compilers. Currently I am developing on GCC on a linux machine and will compile on MSVC before committing the code. To make the cross-compiling easy, I am compiling with -ansi and -pedantic flags. This worked well until I started using snprintf which is not available in C89 standard. GCC can compile this without the -ansi switch but MSVC will fail always as it doesn't have C99 support.

So I did something like,

#ifdef WIN32 
#define snprintf sprintf_s
#endif

This works well because snprintf and sprintf_s has same signatures. I am wondering is this the correct approach?

Any help would be appreciated.

+1  A: 

No. Your approach is doomed to failure.

sqrt and cos have the same prototype. Do you think you can swap them in a program and obtain the same behaviour from before / after the change?


Edit

You probably should write your own snprintf (or download an implementation from the internet [ google is your friend ]) and use that both in Linux and Windows.

http://www.google.com/search?q=snprintf+implementation

pmg
thanks. i will try a custom implementation.
Appu
+2  A: 

I found this on using _snprintf() as an alternative, and the gotchas involved if the buffer overrun protection actually triggers. From what I could see at a quick glance, similar caveats apply to sprintf_s.

Oh, and don't forget to send a mail to Microsoft demanding they support current language standards. (I know they already announced they have no plan to support C99, but bugger them anyway. They deserve it.)

Bottom line, if you want to play it really safe, you'll have to provide your own snprintf() (a wrapper around _snprintf() or sprintf_s() catching their non-standard behaviour) for MSVC.

DevSolar
I suggest a "contract wrapper" around existing implementations (as mentioned in the answer) instead of dragging any third-party code into your project (as suggested by pmg). A complete `*printf()` implementation is quite large.
DevSolar
@DevSolar: Actually a complete `printf` implementation can be very small. Normally I would agree with your principle of wrapping broken implementations rather than reimplementing them, but since Windows' `*printf` also has some broken things you can't easily wrap away (like backwards interpretation of `%s` and `%ls` in the wide variants), I wonder if just replacing it might be the best approach.
R..
Actually another thing you can fix at the same time is MS's inexact floating point printing.
R..
A *naive* `*printf()` implementation can be very small. A *complete* one can become quite something. My own implementation (admittedly written in a not-very-terse style) has a bit over 500 lines already, *without* support for %e, %f, %g, wide chars, or multibyte format strings.
DevSolar