13

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

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
vico
  • 17,051
  • 45
  • 159
  • 315

4 Answers4

20

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.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
12

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.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
3

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.

Yirkha
  • 12,737
  • 5
  • 38
  • 53
2

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765