虽然通过一些c ++代码作为PCI DSS认证审核的一部分,但我遇到了以下内容:
我在我们使用的某个库中有一个方法,其中一个参数是char *,让我们说这是
void foo(char* arg);
代码中调用此方法的点如下所示:
char mystring[256];
strcpy(mystring, "some value");
....
foo(mystring);
作为评论的一部分,我们正在摆脱任何strcpy调用(虽然在这个例子中它有点微不足道,因为“某些值”明显适合mystring)
所以我们得到:
char mystring[256];
strncpy(mystring, "some value", sizeof(mystring));
mystring[sizeof(mystring)-1] = '\0';
....
foo(mystring);
这是因为我想
foo("some value")
会传递const char *
令我惊讶的是,编译器(gcc 4)对此非常满意。当我添加-Wall或-Wcast-qual
时,它甚至不会发出任何警告我的问题是:在这种情况下,当我不知道foo对其参数实际做了什么(如果有的话)时,我可以安全地调用foo(“某些值”)吗?
答案 0 :(得分:10)
不,如果你不能保证foo不会修改参数,那就不安全了。编译器可以隐式地将字符串文字强制转换为char *
,以便与C代码向后兼容(遗憾的是)。您必须将文字复制到可修改的字符缓冲区并传递它。
答案 1 :(得分:8)
在我不知道
foo("some value")
对其参数实际做了什么(如果有的话)时,我可以安全地调用foo
吗?
没有。字符串文字是常量,尝试修改它会产生未定义的行为。
由于历史原因,对于非const char*
有一个过时的转换,一些编译器会允许这种转换 - 尽管这种转换从C ++ 11开始不再有效。您不应该依赖它,并希望您可以在编译器上调高警告级别以防止它。
令我惊讶的是,编译器(gcc 4)对此非常满意。
这令人惊讶。我的GCC 4.6.3默认发出警告;我需要指定-Wno-write-strings
来使其保持沉默。
答案 2 :(得分:2)
strncpy
错了。 size参数应该是 destination 缓冲区的大小减一:
char mystring[256];
strncpy(mystring, "some value", 255);
mystring[255] = '\0';
目标是避免溢出缓冲区。