【发布时间】:2014-10-22 17:56:04
【问题描述】:
最近,我注意到一个奇怪的案例,我想验证一下:
对于 SUS,对于格式字符串中的 %n,相应的 int 将设置为写入到输出的字节数。
此外,对于snprintf(dest, 3, "abcd"),dest 将指向"ab\0"。为什么?因为要写入输出(dest 缓冲区)的字节数不超过 n (n = 3)。
我为代码推断了这一点:
int written;
char dest[3];
snprintf(dest, 3, "abcde%n", &written);
written 将设置为 2(从计数中排除空终止)。
但是根据我使用 GCC 4.8.1 进行的测试,written 设置为 5。
我是否误解了标准?它是一个错误吗?是未定义的行为吗?
编辑:
@wildplasser 说:
...格式字符串中 %n 的行为可能未定义或实现已定义...
和
...实现必须模拟处理完整的格式字符串(包括 %n)...
@par 说:
written是 5,因为这是在遇到%n时将写入的字符数。这是正确的行为。snprintf最多只能复制size字符减去尾随的 null ...
还有:
另一种看待这个问题的方式是,如果
%n只处理最多 2 个字符,甚至不会遇到它,因此可以想象written的值无效......
还有:
...整个字符串通过
printf()规则处理,然后应用最大长度...
是否可以验证为标准、标准草案或某些官方来源?
【问题讨论】:
-
对我来说看起来像一个错误(在库实现中)。
-
我希望您应该首先查看 snprintf() 的返回值。 “副作用”是不同的;如果返回值 >= 第二个参数,则格式字符串中
%n的行为可能未定义或实现已定义。在任何情况下,实现都必须模拟处理完整格式字符串(包括%n)以获得正确的返回值,因此可以获得副作用在飞行中。
标签: c gcc c99 format-string