Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using snprintf in a cross-platform application

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?

like image 501
Navaneeth K N Avatar asked Oct 20 '10 09:10

Navaneeth K N


People also ask

What is the difference between Sprintf and Snprintf?

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 .

What is the use of Snprintf?

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.

What does Snprintf return?

The snprintf() function returns the number of bytes that are written in the array, not counting the ending null character.

Where is Snprintf defined in C?

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.


1 Answers

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 and count 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.

like image 146
DevSolar Avatar answered Oct 25 '22 04:10

DevSolar