为什么std :: strcpy仍可用于char copyTo [0]之类的目的地?

时间:2019-06-22 23:56:16

标签: c++ string 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;
}

2 个答案:

答案 0 :(得分:1)

  

我实际上希望测试失败

为什么?

任何类型的故障都将意味着以下两种情况之一:

  • 由于不确定的行为

  • 而崩溃
  • std::strcpy引发的其他错误,该错误对其参数进行了一些检查

std::strcpy不会对其参数进行任何检查(由于性能原因),并且明确指出它是未定义的行为尝试使用它来写入没有足够大的缓冲区。这意味着也可能发生崩溃(或其他失败迹象),但是由于未定义的行为,而不是由于某些诊断确定了缓冲区不正确。 / p>

  

[...]似乎目的地的大小无关紧要,只要它是指向char数组的有效指针即可

要编译和运行代码? 。为了使代码格式正确?

您的代码表现出不确定的行为,并且无法预测其结果。它似乎可以工作,可能会崩溃,它似乎只能在星期五工作,或者它可以开始将内容无限期地输出到stdout。

请记住-您 不能 期望表现出未定义行为< / em>。

答案 1 :(得分:1)

这不起作用。也许是的。 Undefined Behavior (UB)就是这样,任何事情都可以发生。


无论如何,原始数组的大小必须为正,这是引入std::array的原因之一。如果您的编译器允许零大小的数组作为扩展名,则超出标准范围。

仍然,假设大小为零的数组确实具有0个元素,则访问任何成员都是UB。

并且std::strcpy()盲目地相信第二个参数指向一个字符串,第一个参数指向一个足够大的缓冲区以存储包含终止null的副本的缓冲区,显然您编写的元素多于零。

顺便说一句,您必须包含<cstring>,而不应该包含using namespace std;