简体   繁体   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?

First of all: I want to state, that I (suppose to) understand in general the C++17 changes for inline variables and how they work.首先:我想 state,我(假设)一般理解 C++17 对内联变量的更改及其工作方式。

For my concrete totally simplified use case, I have some kind of a definitions.inl file, that looks like this:对于我完全简化的具体用例,我有某种定义.inl 文件,如下所示:

MY_STRUCT_BEGIN(PotentiallyUB)
MY_STRUCT_END(PotentiallyUB)

And the according macros are defined here inside a header:并且在 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 {};

I'm totally aware of the fact, that the usage of the built-in COUNTER might be questioned here in general, that's another possible issue I do not want to address here.我完全清楚这样一个事实,即内置 COUNTER 的使用通常会在这里受到质疑,这是我不想在这里解决的另一个可能的问题。 Here it is required to emphasize my concerns.这里需要强调我的担忧。 I also know, that static constexpr variables are implicitly inlined since C++17, just added it to make things clear on first sight.我也知道,自 C++17 以来,static constexpr 变量被隐式内联,只是为了让事情一目了然。

Now my question: Is this potentially undefined behavior as soon as the.inl file gets (accidentally or desired) processed across multiple translation units?现在我的问题是:一旦 .inl 文件(意外或需要)跨多个翻译单元处理,这是否可能是未定义的行为? In terms of undefined behavior here, I meant the invariant usage of the difference of MyValue2 - MyValue1 in the definition of MyTranslationUnitIndependentDiff especially.就此处未定义的行为而言,我的意思是 MyValue2 - MyValue1 在 MyTranslationUnitIndependentDiff 的定义中的差异的不变用法。

The standard states标准规定

There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical.只要每个定义出现在不同的翻译单元中,并且(对于非静态内联函数和变量(C++17 起)) 所有定义都是相同的。 For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.例如,内联 function 或内联变量 (C++17 起) 可以在多个源文件中 #include 的 header 文件中定义。

And

If an inline function or variable (since C++17) with external linkage is defined differently in different translation units, the behavior is undefined.如果内联 function 或具有外部链接的变量(C++17 起)在不同的翻译单元中定义不同,则行为未定义。

Especially with focus on the last phrase, I'd currently say, the code shouldn't lead to potential undefined behavior.尤其是关注最后一句话,我目前想说的是,代码不应导致潜在的未定义行为。 But I feel like I might have missed something here.但我觉得我可能在这里错过了一些东西。

Appendix: What I want to achieve附录:我想要达到的目标

I actually want instances of these Macro defined structs as constexpr objects available across all translation units, if possible via external linkage.我实际上希望这些宏定义的结构的实例作为 constexpr 对象在所有翻译单元中可用,如果可能的话,通过外部链接。 I doubt that the external linkage is really possible in the way the declaration of these objects could be handled in a constexpr context project-wide.我怀疑外部链接是否真的可以在项目范围内的 constexpr 上下文中处理这些对象的声明。 If it would be possible, the question about UB should actually not differ since the macro solely affects value initialization and not the definition.如果可能的话,关于 UB 的问题实际上应该没有什么不同,因为宏只影响值初始化而不是定义。

You can put all the code in an anonymous namespace:您可以将所有代码放在匿名命名空间中:

namespace
{
    ...
}

Then each translation unit will have its own separate namespace which are guaranteed not to collide.然后每个翻译单元将有自己独立的命名空间,保证不会发生冲突。

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

相关问题 C++17 内联变量 vs 内联 static 变量 - C++17 inline variable vs inline static variable Class type undefined in static member lambda function in C++17 - Class type undefined in static member lambda function in C++17 为什么C ++ 17中的全局内联变量和静态内联成员需要保护? - Why do global inline variables and static inline members in C++17 need guards? c ++ 17:仅标题:类静态变量错误 - c++17: header only: class static variable errors C++17 内联成员可以强制跨 TU 的全局变量的初始化顺序吗? - Can initialization order of global variables across TUs be forced with C++17 inline members? class模板中static内联成员变量的初始化顺序(C++17) - Initialization order of static inline member variables in class templates (C++17) 跨编译单元的内联方法中的 Static 变量 - Static variable in an inline method across compilation units C ++ 17静态内联成员的编译器错误 - Compiler error with C++17 static inline members 交换 const 成员是未定义的行为吗? C++17 - Is swapping a const member undefined behavior? C++17 释放由全局替换运算符 new 返回的指针,而不调用替换运算符 delete 是未定义的行为吗? (C++17) - Is it undefined behavior to deallocate a pointer returned by a global replacement operator new, without calling a replacement operator delete? (C++17)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM