C++ 为什么std::strcpy仍然适用于像char copyTo[0]这样的目标?

C++ 为什么std::strcpy仍然适用于像char copyTo[0]这样的目标?,c++,string,std,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?

这个测试实际上通过了,似乎目的地的大小无关紧要,只要它是指向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;
}
#包括“gtest/gtest.h”
#包括
使用名称空间std;
测试(练习、书本){
const char*copyFrom=“你好,世界!”;
char copyTo[0];//TODO:它为什么有效?
std::strcpy(copyTo,copyFrom);
期待斯特雷克(“你好,世界!”,copyTo);
标准::cout
我真的以为考试会失败

为什么?

任何类型的失败都意味着两件事之一:

  • 由于未定义的行为而崩溃

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

std::strcpy
不会对其参数执行任何检查(由于性能原因),并且它明确表示尝试使用它写入不够大的缓冲区是未定义的行为。这意味着崩溃(或其他故障迹象)也可能发生,但这是由于未定义的行为,而不是由于某些确定缓冲区不正确的诊断

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

对于要编译和运行的代码?。对于格式良好的代码?

你的代码表现出未定义的行为,你无法预测它的结果。它可能看起来有效,可能崩溃,可能只在周五有效,或者它可以开始无限量地向stdout输出内容

请记住,对于表现出未定义行为的代码,您不能期望任何东西

我真的以为考试会失败

为什么?

任何类型的失败都意味着两件事之一:

  • 由于未定义的行为而崩溃

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

std::strcpy
不会对其参数执行任何检查(由于性能原因),并且它明确表示尝试使用它写入不够大的缓冲区是未定义的行为。这意味着崩溃(或其他故障迹象)也可能发生,但这是由于未定义的行为,而不是由于某些确定缓冲区不正确的诊断

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

对于要编译和运行的代码?。对于格式良好的代码?

你的代码表现出未定义的行为,你无法预测它的结果。它可能看起来有效,可能崩溃,可能只在周五有效,或者它可以开始无限量地向stdout输出内容

请记住,对于表现出未定义行为的代码,您不能期望任何东西。

它不起作用。或者它确实起作用。就像这样,允许任何事情发生


无论如何,原始数组必须具有正大小,这是引入的原因之一。如果编译器允许零大小数组作为扩展,则超出了标准

不过,假设一个大小为零的数组实际上有0个元素,那么访问任何成员都是不可能的

由于盲目相信第二个参数指向一个字符串,第一个参数指向一个足够大的缓冲区来存储一个包含终止null的副本,因此显然您要写入的元素超过了零

顺便说一句,您必须包含
,并且不应该
使用名称空间std;
它不起作用。或者它确实起作用。就像这样,允许任何事情发生


无论如何,原始数组必须具有正大小,这是引入的原因之一。如果编译器允许零大小数组作为扩展,则超出了标准

不过,假设一个大小为零的数组实际上有0个元素,那么访问任何成员都是不可能的

由于盲目相信第二个参数指向一个字符串,第一个参数指向一个足够大的缓冲区来存储一个包含终止null的副本,因此显然您要写入的元素超过了零


另一方面,您必须包含
,并且不应该使用命名空间std;

当代码有这样的错误时,它通常不会达到您预期的效果。这就是为什么避免这样的错误很重要。我还要注意,您在代码中的注释说“它可以工作”。为什么您会将您不期望的行为描述为代码工作?通常,我们说代码在实现我们期望的功能时工作,而不是在实现与我们期望的不同功能时工作。另请注意
char copyTo[0];
首先不是一个有效的定义:不允许使用大小为零的原始数组。当代码有这样的错误时,它通常不会达到预期效果。这就是为什么避免这样的错误很重要。我还要注意,您在代码中的注释说“它可以工作”。为什么您会将不期望的行为描述为代码正常工作?通常,我们说代码正常工作是因为它符合我们的期望,而不是因为它执行了与我们期望不同的操作。另外请注意,
char copyTo[0];
首先不是一个有效的定义:不允许使用大小为零的原始数组。