为什么 std::strcpy 仍然适用于像 char copyTo[0] 这样的目的地?
How come std::strcpy still works for an destination like char copyTo[0]?
这个测试居然通过了,看来目的地的大小并不重要,只要它是一个指向char数组的有效指针即可。
我实际上预计测试会失败,如有任何解释,我们将不胜感激。
#include "gtest/gtest.h"
#include <string>
using namespace std;
TEST(practice, book) {
const char * copyFrom = "Hello World!";
char copyTo[0]; //TODO: why it works?
std::strcpy(copyTo, copyFrom);
EXPECT_STREQ("Hello World!", copyTo);
std::cout << copyTo << std::endl;
}
I actually expected the test to fail
为什么?
任何类型的失败都意味着以下两种情况之一:
由于未定义的行为导致崩溃
std::strcpy
引发的其他错误,它对其参数进行了一些检查
std::strcpy
不对其参数执行任何检查(由于性能原因)并且它明确声明它是 未定义的行为 尝试使用它写入缓冲区不够大。这意味着崩溃(或其他故障迹象)也可能发生,但由于未定义的行为,而不是由于某些诊断确定缓冲区不正确。
[...] it seems that the size of the destination doesn't matter, as long as it is a valid pointer to a char array
对于要编译的代码和运行? 是。代码是well-formed? 没有.
您的代码表现出未定义的行为,无法预测其结果。它可能看起来可以工作,也可能会崩溃,它可能似乎只在星期五工作,或者它可以开始无限地向标准输出输出内容。
记住 - 你不能期望任何东西来自展示未定义的行为.
它不起作用。或者也许是这样。 Undefined Behavior (UB)就是这样,允许任何事情发生。
无论如何,原始数组的大小必须为正数,这是引入 std::array
的原因之一。如果您的编译器允许 zero-sized 数组作为扩展,那就超出了标准。
不过,假设 zero-sized 数组确实有 0 个元素,访问任何成员都是 UB。
并且由于 std::strcpy()
盲目地相信第二个参数指向一个字符串,而第一个参数指向一个足够大的缓冲区来存储包括终止 null 的副本,显然你写的元素多于零。
顺便说一句,您必须包括 <cstring>
,而不应该包括 using namespace std;
。
这个测试居然通过了,看来目的地的大小并不重要,只要它是一个指向char数组的有效指针即可。
我实际上预计测试会失败,如有任何解释,我们将不胜感激。
#include "gtest/gtest.h"
#include <string>
using namespace std;
TEST(practice, book) {
const char * copyFrom = "Hello World!";
char copyTo[0]; //TODO: why it works?
std::strcpy(copyTo, copyFrom);
EXPECT_STREQ("Hello World!", copyTo);
std::cout << copyTo << std::endl;
}
I actually expected the test to fail
为什么?
任何类型的失败都意味着以下两种情况之一:
由于未定义的行为导致崩溃
std::strcpy
引发的其他错误,它对其参数进行了一些检查
std::strcpy
不对其参数执行任何检查(由于性能原因)并且它明确声明它是 未定义的行为 尝试使用它写入缓冲区不够大。这意味着崩溃(或其他故障迹象)也可能发生,但由于未定义的行为,而不是由于某些诊断确定缓冲区不正确。
[...] it seems that the size of the destination doesn't matter, as long as it is a valid pointer to a char array
对于要编译的代码和运行? 是。代码是well-formed? 没有.
您的代码表现出未定义的行为,无法预测其结果。它可能看起来可以工作,也可能会崩溃,它可能似乎只在星期五工作,或者它可以开始无限地向标准输出输出内容。
记住 - 你不能期望任何东西来自展示未定义的行为.
它不起作用。或者也许是这样。 Undefined Behavior (UB)就是这样,允许任何事情发生。
无论如何,原始数组的大小必须为正数,这是引入 std::array
的原因之一。如果您的编译器允许 zero-sized 数组作为扩展,那就超出了标准。
不过,假设 zero-sized 数组确实有 0 个元素,访问任何成员都是 UB。
并且由于 std::strcpy()
盲目地相信第二个参数指向一个字符串,而第一个参数指向一个足够大的缓冲区来存储包括终止 null 的副本,显然你写的元素多于零。
顺便说一句,您必须包括 <cstring>
,而不应该包括 using namespace std;
。