constexpr 函数是隐式静态的吗?
Are constexpr functions implicitly static?
如果我在 program.cpp
中定义一个函数:
constexpr bool isThree(const int number)
{
return number == 3;
}
这与声明它为静态有什么不同吗?
static constexpr bool isThree(const int number)
{
return number == 3;
}
看起来这些应该是等价的,因为 constexpr
意味着函数是内联的,因此不在编译单元之间共享。
constexpr
全局函数是隐式静态的吗?
constexpr
函数隐式 inline
.
inline
是一个链接功能。在不同编译单元中定义的 inline
函数不是错误;如果它们的定义不同,则您的程序 ill-formed 不需要诊断,但如果它们具有相同的定义,则除一个版本外的所有版本都将被丢弃并使用该版本。
static
,在 non-method 函数上,也是一个链接功能。 static
定义不在其编译单元之外共享;编译单元没有 'advertise' 它有 isThree
.
的定义
方法函数上的 static
与链接无关。在那种情况下,它只是意味着 this
没有隐式传递给函数。一种方法 with/without this
它不起作用有差异,但它们大多与 constexpr
无关。请注意,至少 c++14 a constexpr
method that doesn't use this
can still be constant evaluated. Some versions of c++ make constexpr
methods implicitly const
; c++17 不会。
一个编译单元中的 &isThree
和另一个编译单元中的 &isThree
可以(并且通常会)在 static
时发生变化(除非激进的 ICF,这是另一个问题的问题)。当 inline
它们可能不会变化。
inline
函数 在编译单元之间共享。它们的完整定义也经常在所有知道它的编译单元中可见,因此它使编译器 "inlining"(与关键字相反)您的代码更容易。 static
不是。 constexpr
函数隐式 inline
,但不是隐式 static
。
请注意,constexpr
函数有时可以在运行时上下文中求值。在编译时上下文中评估时,它们的 inline
与 static
或链接状态真的无关紧要。
constexpr
也有其他含义,但您想知道两个不同的 constexpr
声明之间的区别,并且 none 这些含义发生了变化。
constexpr
函数不是隐式静态的。它们与非 constexpr
函数具有相同的链接:
// external linkage
constexpr int f1(int x) { /* ... */ }
// internal linkage
static constexpr int f2(int x) { /* ... */ }
// internal linkage
namespace {
constexpr int f3(int x) { /* ... */ }
}
// no linkage
void enclosing() {
struct S {
constexpr int f4(int x) { /* ... */ }
};
}
当一个constexpr
函数有外部链接时,它在所有翻译单元中有相同的地址。当它有内部链接时,每个翻译单元都有一个不同的副本,这些副本有不同的地址。但是,我相信 调用 一个 constexpr
函数的结果不应该取决于它是否具有内部或外部链接(因为 constexpr
函数可能不包含静态变量) .
如果我在 program.cpp
中定义一个函数:
constexpr bool isThree(const int number)
{
return number == 3;
}
这与声明它为静态有什么不同吗?
static constexpr bool isThree(const int number)
{
return number == 3;
}
看起来这些应该是等价的,因为 constexpr
意味着函数是内联的,因此不在编译单元之间共享。
constexpr
全局函数是隐式静态的吗?
constexpr
函数隐式 inline
.
inline
是一个链接功能。在不同编译单元中定义的 inline
函数不是错误;如果它们的定义不同,则您的程序 ill-formed 不需要诊断,但如果它们具有相同的定义,则除一个版本外的所有版本都将被丢弃并使用该版本。
static
,在 non-method 函数上,也是一个链接功能。 static
定义不在其编译单元之外共享;编译单元没有 'advertise' 它有 isThree
.
static
与链接无关。在那种情况下,它只是意味着 this
没有隐式传递给函数。一种方法 with/without this
它不起作用有差异,但它们大多与 constexpr
无关。请注意,至少 c++14 a constexpr
method that doesn't use this
can still be constant evaluated. Some versions of c++ make constexpr
methods implicitly const
; c++17 不会。
&isThree
和另一个编译单元中的 &isThree
可以(并且通常会)在 static
时发生变化(除非激进的 ICF,这是另一个问题的问题)。当 inline
它们可能不会变化。
inline
函数 在编译单元之间共享。它们的完整定义也经常在所有知道它的编译单元中可见,因此它使编译器 "inlining"(与关键字相反)您的代码更容易。 static
不是。 constexpr
函数隐式 inline
,但不是隐式 static
。
请注意,constexpr
函数有时可以在运行时上下文中求值。在编译时上下文中评估时,它们的 inline
与 static
或链接状态真的无关紧要。
constexpr
也有其他含义,但您想知道两个不同的 constexpr
声明之间的区别,并且 none 这些含义发生了变化。
constexpr
函数不是隐式静态的。它们与非 constexpr
函数具有相同的链接:
// external linkage
constexpr int f1(int x) { /* ... */ }
// internal linkage
static constexpr int f2(int x) { /* ... */ }
// internal linkage
namespace {
constexpr int f3(int x) { /* ... */ }
}
// no linkage
void enclosing() {
struct S {
constexpr int f4(int x) { /* ... */ }
};
}
当一个constexpr
函数有外部链接时,它在所有翻译单元中有相同的地址。当它有内部链接时,每个翻译单元都有一个不同的副本,这些副本有不同的地址。但是,我相信 调用 一个 constexpr
函数的结果不应该取决于它是否具有内部或外部链接(因为 constexpr
函数可能不包含静态变量) .