gpt4 book ai didi

c++ - 命名空间范围内的 constexpr 变量,有和没有显式内联定义

转载 作者:行者123 更新时间:2023-11-30 03:14:14 24 4
gpt4 key购买 nike

即使在阅读之后this question about non explicit inline namespace scoped variables ,在 header 中定义,我有点偏执地认为显式内联命名空间范围变量是可以的,因为 AFAIK 违反 ODR 是 UB,不需要诊断。我的理解是否正确,在命名空间范围内显式内联指定的 constexpr(和 const 非 volatile 类似)定义的变量是内联变量,因此它们的 ODR 用法在不同的翻译单元中使用时可以吗?甚至 cppreference.com 也自相矛盾,有时它说内联变量必须是外部的 ODR 使用异常,而在另一个页面上,通常只有内部链接内联变量是可以的,只有在有额外要求的情况下才是外部的。

基本上这些假设是正确的吗?:

/*! @file some_header.hpp */
#ifndef HEADER_GUARD
#define HEADER_GUARD

constexpr int global_non_expl_inline = 42; //UB
static constexpr int global_non_expl_inline_static = 42; //UB
inline int global_expl_inline = 42; //ok
inline int static global_expl_inline_explicit_static = 42; //? external linkage by default but static explicit but still ok?
inline int extern global_expl_inline_explicit_extern = 42; //UB

namespace foo {
constexpr int global_non_expl_inline = 42; //UB
static constexpr int global_non_expl_inline_static = 42; //UB
inline int global_expl_inline = 42; //ok
inline int static global_expl_inline_explicit_static = 42; //? external linkage by default but static explicit but still ok?
inline int extern global_expl_inline_explicit_extern = 42; //UB
}

namespace {
inline int extern global_expl_inline_explicit_extern_but_unnamed_ns = 42; //ok
}

struct bar{
static int const in_class_static = 42;//ok
static int in_class_but_out_of_source_def;
};

int bar::in_class_but_out_of_source_def = 42;//UB

#endif

最佳答案

嗯...既然你真的设法让我自己对你的问题感到困惑,我想我会进一步研究它。首先,我们必须对变量的相关属性进行分类:生命周期、可见性、链接这些受关键字影响:staticinlineconstexprconstextern 您在问题中使用的。

在变量定义的命名空间范围内:
- static: 指定内部链接
- inline:允许在不同的翻译单元中对同一变量进行多个相同的定义,并确保它们将引用同一对象(例如,具有相同的地址)
- constexpr: 暗示const- const: 默认为外部链接
- extern: 指定外部链接

因此,
- global_non_expl_inline:默认为外部链接。没问题,除非另一个翻译单元定义了另一个具有外部链接的此类变量。
- global_non_expl_inline_static:内部链接。可以,只要您不在任何地方定义其他此类变量即可。
- global_expl_inline:外部链接和内联。没问题,除非另一个翻译单元声明另一个没有 inline 的此类变量。
- global_expl_inline_explicit_static:很好,static inline 变量是有意义的,如果您不希望它在链接时可用,但又希望在所有翻译单元中使用相同的变量- 例如对各种常量有用。
- global_expl_inline_explicit_extern:外部链接和内联。没问题,除非另一个翻译单元声明另一个没有 inline 的此类变量。
- global_expl_inline_explicit_extern_but_unnamed_ns:内部链接根据cppreference .

在类范围内:
- in_class_static:外部链接。很好,根据cppreference , 但如果它是 ODR 使用的,则需要在命名空间范围内声明。
- in_class_but_out_of_source_def:外部链接。还可以。这实际上是标准方式。

总而言之,未定义的行为比您想象的要少得多——这很好。然而,有一些东西是有效的,但实际上没有意义,例如未命名 namespace 中的 extern

关于您对此问题的评论:我无法重现该问题,该问题评论部分的其他人也无法重现。您可以在其评论部分找到该问题的其他合理性问题。请记住,提出一些关于 stackoverflow 的问题的人并不清楚在遇到问题时他们采取了哪些步骤。我不会太在意那个特定的问题;)

关于c++ - 命名空间范围内的 constexpr 变量,有和没有显式内联定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58065751/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com