代码之家  ›  专栏  ›  技术社区  ›  jnj

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

  •  0
  • jnj  · 技术社区  · 6 年前

    这个测试实际上通过了,似乎目的地的大小无关紧要,只要它是指向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 回复  |  直到 6 年前
        1
  •  1
  •   Fureeish    6 年前

    我真的以为考试会失败

    为什么?

    任何一种失败都意味着两件事之一:

    • 由于 未定义行为

    • 引起的其他错误 std::strcpy 对它的论点进行了一些检查

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

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

    让代码编译和运行? 是的 .代码格式正确吗? 是的。

    你的代码表现出未定义的行为,人们无法预测其结果。它可能看起来工作,可能崩溃,可能看起来只在周五工作,或者它可以开始无限量地向stdout输出数据。

    记住-你 不能 期待 任何东西 从一个显示 未定义行为 是的。

        2
  •  1
  •   Deduplicator    6 年前

    不是的 工作 .或者是真的。 Undefined Behavior (UB) 就像那样,允许任何事情发生。


    无论如何,原始数组的大小必须为正,这是原因之一 std::array 被介绍了。如果编译器允许将零大小的数组作为扩展,则这超出了标准。

    不过,假设一个零大小的数组真的有0个元素,那么访问任何成员都是ub。

    作为 std::strcpy()

    作为旁白,你必须包括 <cstring> ,不应该 using namespace std; 是的。