Wil*_*olf 9 c standards pointers restrict-qualifier asprintf
情况是这样的:
我们从外部源收到了使用 sprintf(如 strcat)的代码。像这样:
char buffer[1024];
sprintf(buffer, "Some text.");
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");
Run Code Online (Sandbox Code Playgroud)
现在,这看起来很奇怪。我们都同意这看起来很奇怪。我要问的不是这个。我们都知道应该用strcat,而且更直接。我问的是除了看起来很奇怪之外,这可能导致的潜在问题。我们在 RHEL6 上运行,并使用 gcc 4.9.3。
感谢您的帮助。
Vla*_*cow 11
该函数声明如下
int sprintf(char * restrict s, const char * restrict format, ...);
Run Code Online (Sandbox Code Playgroud)
注意类型限定符restrict。
根据 C 标准(7.21.6.6 sprintf 函数)
2 sprintf 函数与 fprintf 等效,只是输出被写入数组(由参数 s 指定)而不是流中。写入的字符末尾写入空字符;它不计入返回值的一部分。 如果复制发生在重叠的对象之间,则行为是未定义的。
所以这些电话
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");
Run Code Online (Sandbox Code Playgroud)
调用未定义的行为。
相反,调用可以写成这样
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");
Run Code Online (Sandbox Code Playgroud)
或者
char buffer[1024];
char *p = buffer;
p += sprintf( p, "Some text.");
p += sprintf( p, "%s", "Some more text");
sprintf( p, "%s", "again more text");
Run Code Online (Sandbox Code Playgroud)
至于限定符restrict,一般来说是指意思(6.7.3 类型限定符)
8 通过限制限定指针访问的对象与该指针具有特殊关联。这种关联在下面的 6.7.3.1 中定义,要求对该对象的所有访问都直接或间接地使用该特定指针的值