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?
The snprintf function is similar to sprintf , except that the size argument specifies the maximum number of characters to produce. The trailing null character is counted towards this limit, so you should allocate at least size characters for the string s .
The snprintf is a predefined library function of the stdio. h header file, which redirects the output of the standard printf() function to other buffers. The snprint() function is used to format the given strings into a series of characters or values in the buffer area.
The snprintf() function returns the number of bytes that are written in the array, not counting the ending null character.
The snprintf() function is defined in the <stdio. h> header file and is used to store the specified string till a specified length in the specified format. Characteristics of snprintf() method: The snprintf() function formats and stores a series of characters and values in the array buffer.
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
.
Can you see the problem? In the Linux version, the output is always null-terminated. In MSVC, it's not.
Even more subtle is the difference between the
size
parameter in Linux andcount
parameter in MSVC. The former is the size of the output buffer including the terminating null and the latter is the maximum count of characters to store, which excludes the terminating null.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With