如果我有一个函数(比方说,一个大阵列)内的变量,它是有意义的声明它既static和constexpr?constexpr保证数组是在编译时创建的,那么它会static没用吗?
void f() {
static constexpr int x [] = {
// a few thousand elements
};
// do something with the array
}
Run Code Online (Sandbox Code Playgroud)
static在生成的代码或语义方面,实际上是在做什么吗?
我正在尝试在编译时计算字符串文字的长度.为此,我使用以下代码:
#include <cstdio>
int constexpr length(const char* str)
{
return *str ? 1 + length(str + 1) : 0;
}
int main()
{
printf("%d %d", length("abcd"), length("abcdefgh"));
}
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作,程序打印4和8.由clang生成的汇编代码显示结果在编译时计算:
0x100000f5e: leaq 0x35(%rip), %rdi ; "%d %d"
0x100000f65: movl $0x4, %esi
0x100000f6a: movl $0x8, %edx
0x100000f6f: xorl %eax, %eax
0x100000f71: callq 0x100000f7a ; symbol stub for: printf
Run Code Online (Sandbox Code Playgroud)
我的问题:标准是否保证length函数将在编译时进行评估?
如果这是真的,编译时字符串文字计算的大门刚刚为我打开...例如,我可以在编译时计算哈希值等等......
我正在寻找标准中对这一事实的正式解释.我已经找到了3.9.1/9所说的内容并尝试用该部分作出解释.
第3.9.1/9节,N3797:
void类型具有一组空值.void类型是不完整的类型,无法完成.它用作不返回值的函数的返回类型.任何表达式都可以显式转换为cv void(5.4)类型.void类型的表达式只能用作表达式语句(6.2),作为逗号表达式(5.18)的操作数,作为?:( 5.16)的第二个或第三个操作数,作为typeid,noexcept或者操作数的操作数. decltype,作为返回类型为void的函数的返回语句(6.6.3)中的表达式,或者作为显式转换为类型cv void的操作数.
我不明白它是如何暗示void类型有一组空的值?
假设类型T具有一组空值.为什么编译器在遇到以下行时会抛出错误:
extern T v;
Run Code Online (Sandbox Code Playgroud)
我们可以通过以下方式对不完整类型的变量进行decalre:
#include <iostream>
#include <cstring>
using namespace std;
struct Foo;
extern Foo f; //OK!
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
它工作正常
它不能在void类型上完成
#include <iostream>
#include <cstring>
using namespace std;
extern void f; //compile-time error
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
我可以在头文件中有这样的定义吗?
constexpr double PI=3.14;
Run Code Online (Sandbox Code Playgroud)
在包含在几个cpp文件中的头文件中有这个问题吗?
我担心,因为它在标准中说这个constexpr有自己的内存,把它放在头文件中,并在几个cpp文件中添加标题,在内存中生成相同值的多个副本以及其他一些令人讨厌的问题.
我正在使用C++ 11
根据https://docs.microsoft.com/zh-cn/cpp/cpp/constexpr-cpp?view=vs-2019
“ constexpr表示该值或返回值是恒定的,并且,如果可能,在编译时进行计算。”
此外,constexpr和静态constexpr全局变量之间的区别
“在变量声明中,constexpr隐含const,并且默认情况下,名称空间范围内的const变量具有内部链接(因此,添加static不会更改任何内容)。”
我认为这constexpr意味着const隐含static。
但是,这个问题的答案使我感到困惑:什么时候以及为什么在constexpr中使用static?
它指出
- “ constexpr变量不是编译时值”
- “看来,在某些特殊情况下,我们可以受益于静态constexpr变量的静态存储持续时间。”
我有什么误会?
我想知道在函数内部定义constexpr变量时内部会发生什么.程序是否存储了被调用函数的constexpr变量的每个版本?
例:
template <class T, std::size_t M, std::size_t N>
template <std::size_t M2, std::size_t N2>
Matrix<T, M, N>::Matrix(const Matrix<T, M2, N2>& m)
{
constexpr T m_min(MATHS::min(M, M2));
constexpr T n_min(MATHS::min(N, N2));
std::size_t i(0), j(0);
for ( ; i < m_min ; ++i )
{
for ( j = 0 ; j < n_min ; ++j )
m_elts[i][j] = m.m_elts[i][j];
for ( ; j < N ; ++j )
m_elts[i][j] = MATHS::CST<T>::ZERO;
}
for ( ; i < M ; ++i ) …Run Code Online (Sandbox Code Playgroud)