断言在内存中,紧随std::span之后的是一个空字节

编程语言 2026-07-09
#include <assert.h>
#include <span>

int main(int argc, char **argv)
{
    // 1) According to the standard, this must pass:
    assert(argv[argc] == nullptr);


    std::span<char *> spn { argv, argv + argc };

    // 2) Undefined behavior
    assert(spn[argc] == nullptr);

    // 3) Is this allowed ?
    assert(spn.data()[argc] == nullptr);
}

这个问题是关于第三个 assert 的。

因为我并不对 span 本身进行下标访问,而是取它的地址,基本上把它当作一个数组来对待,我相信这是正确的(并且它能通过测试)。
据ChatGPT所述,这属于有定义的行为。

所以问题是:
第三条断言语句是否属于有定义的行为,且它会通过吗?

解决方案

这不是未定义行为。

std::span 的构造函数是基于 data() 构造完成后将返回什么来定义的。在用 (argv, argv+argc) 构造得到 std::span 之后,data() 等于 argv。所以 spn.data()[argc]argv[argc] 无法区分。

你也可以做 *std::to_address(spn.end())

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章