最近 ubuntu/debian 正在讨论 sprintf/snprintf 的问题,我在这描述一遍。
sprintf 的原型为:
int sprintf(char *restrict s, const char *restrict format, ...);
其中 char* restrict s 的含义为经过s 指向的内存空间不得与其余指针参数指向的内存的空间重叠。好比以下的语句就是错误的用法, 由于参数1与参数3指向的内存重叠了。但这种作法做为加强版的 strcat 已被普遍使用。
sprintf(buf, "%s foo %d %d", buf, var1, var2);
在 ubuntu 8.10 所带的 gcc 中,若是编译时加入了优化选项(好比 -O1, -O2), 那么sprinf 会首先将 s 清空,好比以下的程序会输出 "fail", 而不是 "not fail"。
#include <stdio.h> char buf[80] = "not ";int main(){sprintf(buf, "%sfail", buf);puts(buf); return 0;}
做为补救方案,能够使用以下的语句来代替:
sprintf(buf+strlen(buf), " foo %d %d", var1, var2);
snprintf 有相似的 bug.
不少 Debian/Ubuntu 包都有此 bug,能够参见以下两个 thread 中的具体内容:
[1]
https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/305901
[2]
http://groups.google.com/group/linux.debian.devel/browse_thread/thread/c5bbda39f1a01bd4
html