情况如下:
我们从外部源代码接收到使用strcat之类的sprintf的代码。这样的:
char buffer[1024];
sprintf(buffer, "Some text.");
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");
现在,这看起来很奇怪。我们都认为这看起来很奇怪。我问的不是这个。我们都知道应该使用strcat,它更直接。我问的是,除了看起来很奇怪之外,这可能会造成的潜在问题。我们在RHEL6上运行,使用的是gcc 4.9.3。
谢谢你的帮助。
函数声明如下
int sprintf(char * restrict s, const char * restrict format, ...);
注意类型限定符restrict
根据C标准(7.21.6.6 . the sprintf函数)
2 sprintf函数等价于fprintf,不同之处在于输出被写入一个数组(由参数s指定)而不是小溪。的末尾写入空字符写字符;它不会被计算在返回值中。如果复制发生在重叠的对象之间,则行为为未定义的.
所以这些调用
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");
调用未定义行为
可以写成
char buffer[1024];
int offset = 0;
offset = sprintf( buffer + offset, "Some text.");
offset += sprintf( buffer + offset, "%s", "Some more text");
sprintf( buffer + offset, "%s", "again more text");
或
char buffer[1024];
char *p = buffer;
p += sprintf( p, "Some text.");
p += sprintf( p, "%s", "Some more text");
sprintf( p, "%s", "again more text");
对于限定词restrict
,则在一般词语中(6.7.3类型限定词)
8通过限制限定指针访问的对象具有与该指针的特殊关联。这种关联,定义在下面的6.7.3.1要求对该对象的所有访问都使用,直接或间接地,指定指针
的值