繁体   English   中英

全局 static 内联变量,可能跨翻译单元重新定义 class - 这种特殊情况是 C++17 中的未定义行为吗?

[英]Global static inline variable with potential class redefinition across translation units - Is this particular case undefined behavior in C++17?

首先:我想 state,我(假设)一般理解 C++17 对内联变量的更改及其工作方式。

对于我完全简化的具体用例,我有某种定义.inl 文件,如下所示:

MY_STRUCT_BEGIN(PotentiallyUB)
MY_STRUCT_END(PotentiallyUB)

并且在 header 中定义了相应的宏:

#define MY_STRUCT_BEGIN(myStructName) \
static inline constexpr struct myStructName##Type\
{ \
  static inline constexpr unsigned long MyValue1 = __COUNTER__ + 1; \
  static inline constexpr unsigned long MyValue2 = __COUNTER__ + 1; \
  static inline constexpr unsigned long MyTranslationUnitIndependentDiff = MyValue2 - MyValue1;

#define MY_STRUCT_END(myStructName) \
} myStructName {};

我完全清楚这样一个事实,即内置 COUNTER 的使用通常会在这里受到质疑,这是我不想在这里解决的另一个可能的问题。 这里需要强调我的担忧。 我也知道,自 C++17 以来,static constexpr 变量被隐式内联,只是为了让事情一目了然。

现在我的问题是:一旦 .inl 文件(意外或需要)跨多个翻译单元处理,这是否可能是未定义的行为? 就此处未定义的行为而言,我的意思是 MyValue2 - MyValue1 在 MyTranslationUnitIndependentDiff 的定义中的差异的不变用法。

标准规定

只要每个定义出现在不同的翻译单元中,并且(对于非静态内联函数和变量(C++17 起)) 所有定义都是相同的。 例如,内联 function 或内联变量 (C++17 起) 可以在多个源文件中 #include 的 header 文件中定义。

如果内联 function 或具有外部链接的变量(C++17 起)在不同的翻译单元中定义不同,则行为未定义。

尤其是关注最后一句话,我目前想说的是,代码不应导致潜在的未定义行为。 但我觉得我可能在这里错过了一些东西。

附录:我想要达到的目标

我实际上希望这些宏定义的结构的实例作为 constexpr 对象在所有翻译单元中可用,如果可能的话,通过外部链接。 我怀疑外部链接是否真的可以在项目范围内的 constexpr 上下文中处理这些对象的声明。 如果可能的话,关于 UB 的问题实际上应该没有什么不同,因为宏只影响值初始化而不是定义。

您可以将所有代码放在匿名命名空间中:

namespace
{
    ...
}

然后每个翻译单元将有自己独立的命名空间,保证不会发生冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM