“_”是什么意思?为什么微软在开头加上这个标记?
4 回答
全局命名空间中以 开头的标识符_
是为实现保留的。_snprintf
只是实现(Visual Studio)提供的一个功能。至于这样做的理由,Visual Studio 实现了 C89,并且snprintf
是后来的 C99 标准的一部分。
除此之外,两个函数的语义在返回类型上有所不同,返回类型snprintf
总是格式化字符串占用的字符数(缓冲区中是否有足够的空间,如果没有则_snprintf
返回负数缓冲区中有足够的空间。
也就是说,要为输出分配一个足够大的缓冲区,您可以执行以下操作:
int size = snprintf( 0, 0, "%s %d\n", str, i );
char * buffer = malloc( size+1 );
snprintf( buffer, size+1, "%s %d\n", str, i );
您不能这样做,_snprintf
因为该函数返回的唯一信息是当前大小不够。
snprintf()
在 Microsoft 的 C 运行时开始支持它时,它还不是标准的一部分。
由于函数原型没有标准化,并且开发人员不想使用该名称snprintf
(以防标准后来指定了不同的原型),他们选择添加一个前导下划线来表示该函数是微软对该标准的扩展。
加上上述,
自 Visual Studio 2015 以来有适当的 C99snprintf()
和可用vsnprintf()
他们甚至不会触发众所周知的不安全功能弃用警告。
_snprintf_s()
或_vsnprintf_s()
,虽然提供,是 MSVC 特定功能的“安全变体”,具有非 C99 行为。
除了在缓冲区不够大的情况下返回值不同(在大卫的回答中描述)之外,组中的函数在另一个重要方面_sn...
与标准不同。如果目标缓冲区只有一个字符snprintf
太短,则函数将这种情况视为“成功”。_sn...
更详细地说,如果目标缓冲区足够长以存储整个结果序列但没有终止零字符,则_sn...
函数不会截断结果,不将终止零写入目标缓冲区并返回缓冲区大小为结果。因此,在一般情况下,不能保证结果为零终止。
在相同的情况下,snprintf
将丢弃结果序列的最后一个字符并在其位置写入零终止符。的结果snprintf
总是以零结尾。