Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why in msvc++ we have _snprintf while other compilers allows snprintf

What "_" means? Why Microsoft adds this mark at the beginning?

like image 404
vico Avatar asked Jul 20 '12 12:07

vico


4 Answers

Aside from a different return value in case of insufficiently large buffer (described in David's answer), functions from _sn... group differ from the standard snprintf in another important regard. If the target buffer is too short by just one character, the _sn... functions consider this situation a "success".

In more detail, if the target buffer is long enough to store the whole resultant sequence but without the terminating zero character, the _sn... functions do not truncate the result, do not write the terminating zero into the target buffer and return the size of the buffer as a result. So, in general case the result is not guaranteed to be zero-terminated.

In the same situation, snprintf will discard the last character of the resultant sequence and write zero terminator in its place. The result of snprintf is always zero-terminated.

like image 143
AnT Avatar answered Oct 18 '22 00:10

AnT


Identifiers in the global namespace starting with _ are reserved for the implementation. _snprintf is just a function that the implementation (Visual Studio) has provided. As to the rationale for that, Visual Studio implements C89, and snprintf is part of a later C99 standard.

Besides that, the semantics of both functions are different in the return type, which in snprintf is always the number of characters that the formatted string takes (whether there was enough space in the buffer or not, while _snprintf will return a negative number if there is not enough space in the buffer.

That is, to allocate a buffer just large enough for the output you can do:

int size = snprintf( 0, 0, "%s %d\n", str, i );
char * buffer = malloc( size+1 );
snprintf( buffer, size+1, "%s %d\n", str, i );

You cannot do that with _snprintf as the only information that the function yields back is that the current size is not enough.

like image 37
David Rodríguez - dribeas Avatar answered Oct 17 '22 23:10

David Rodríguez - dribeas


snprintf() was not yet part of the standard at the time Microsoft's C runtime began to support it.

Since the function prototype was not standardized, and the developers did not want to use the name snprintf (in case the standard later specified a different prototype), they opted to add a leading underscore to denote the function as being a Microsoft extension to the standard.

like image 23
Frédéric Hamidi Avatar answered Oct 18 '22 00:10

Frédéric Hamidi


Adding to the above,

there are proper C99 snprintf() and vsnprintf() available since Visual Studio 2015

and they do not even trigger the well known unsafe function deprecation warning.
_snprintf_s() or _vsnprintf_s(), while provided, are "secure variants" of the MSVC-specific functions, with the non-C99 behavior.

like image 41
Yirkha Avatar answered Oct 18 '22 01:10

Yirkha