8赞
866
当前位置:  开发笔记 > 编程语言 > 正文

标题中的`const`和`constexpr`变量应该是'inline`以防止ODR违规吗?

如何解决《标题中的`const`和`constexpr`变量应该是'inline`以防止ODR违规吗?》经验,为你挑选了1个好方法。

考虑以下标题并假设它在多个TU中使用:

static int x = 0;

struct A {
    A() {
        ++x;
        printf("%d\n", x);
    }
};

正如这个问题所解释的那样,这是ODR违规,因此也就是UB.

现在,如果我们的函数引用非对象并且我们不在该函数中使用它(加上其他条款),则不存在ODR违规,因此这在头文件中仍然可以正常工作:inlinevolatile const

constexpr int x = 1;

struct A {
    A() {
        printf("%d\n", x);
    }
};

但如果我们确实碰巧使用它,我们又回到UB的第一个方面:

constexpr int x = 1;

struct A {
    A() {
        printf("%p\n", &x);
    }
};

因此,鉴于我们现在有inline变量,指南是否应该在标题中标记所有namespace变量inline以避免所有问题?

constexpr inline int x = 1;

struct A {
    A() {
        printf("%p\n", &x);
    }
};

这似乎也更容易教,因为我们可以简单地说" inline标题中的所有内容"(即函数和变量定义),以及"从不static在标题中".

这个推理是否正确?如果是的话,总是在标题中标记constconstexpr变量是否有任何缺点inline



1> Jans..:

正如您所指出的,根据[basic.def.odr] /12.2.1,示例一和三确实违反了ODR.

[...]在D的每个定义中,相应的名称,根据[basic.lookup]查找,应指在D的定义内定义的实体,或者在重载解析后和匹配后应引用同一实体.部分模板特化,除了名称可以引用

一个非易失性const对象,如果是对象,则内部或没有链接

在D的任何定义中都没有用过,[..]

这个推理是否正确?

是的,具有外部链接的内联变量保证引用同一个实体,即使它们使用的时间长,所有定义都相同:

[dcl.inline]/6

内联函数或变量应在每个使用过的翻译单元中定义,并且在每种情况下都应具有完全相同的定义([basic.def.odr]).[..]具有外部链接的内联函数或变量在所有翻译单元中应具有相同的地址.

最后一个例子是可以的,因为它符合并且不违反上述的粗体部分.

总是将标题中的const和constexpr变量标记为内联是否有任何缺点?

我想不出任何一个,因为如果我们保证通过TU的外部链接具有完全相同的内联变量定义,编译器可以自由选择它们中的任何一个来引用变量,这将是相同的从技术上讲,只有一个TU,并在标题中声明了一个带有适当标题保护的全局变量

推荐阅读
devbox
空荡荡跑龙套
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有 京ICP备19059560号-4