当我使用 constexpr 函数时,我注意到一个奇怪的行为。我将代码简化为一个简化的示例。从两个不同的翻译单元(模块 A 和 B)调用两个函数。
#include <iostream>
int mod_a();
int mod_b();
int main()
{
std::cout << "mod_a(): " << mod_a() << "\n";
std::cout << "mod_b(): " << mod_b() << "\n";
std::cout << std::endl;
return 0;
}
这些模块看起来很相似。这是 mod_a.cpp:
constexpr int X = 3;
constexpr int Y = 4;
#include "common.h"
int mod_a()
{
return get_product();
}
只有一些内部常数不同。这是 mod_b.cpp:
constexpr int X = 6;
constexpr int Y = 7;
#include "common.h"
int mod_b()
{
return get_product();
}
两个模块都使用constexpr
“common.h”中定义的通用函数:
/* static */ constexpr int get_product()
{
return X * Y;
}
我很惊讶这两个函数都返回 12。由于#include
指令(应该只包含一些源代码),我认为两个模块之间没有交互。当我get_product
也定义为时static
,行为如预期:
mod_a()
返回 12,
mod_b()
返回 42。
我还在https://www.youtube.com/watch?v=4pKtPWcl1Go上查看了 Jason Turner 的 C++ Weekly: Stop Using 'constexpr' (And Use This!) 第 312 集。
一般使用的建议static constexpr
是一个很好的提示。
但我仍然想知道我在没有static
关键字的情况下注意到的行为是否定义明确。还是UB?或者它是一个编译器错误?
除了constexpr
函数,我还尝试了一个 C 风格的宏#define get_product() (X*Y)
,它也向我展示了预期的结果(12 和 42)。
小心
迈克尔