gpt4 book ai didi

c++14 - 如何防止意外发出 constexpr 函数

转载 作者:行者123 更新时间:2023-12-02 09:18:46 24 4
gpt4 key购买 nike

Ben Deane 提到 the throw trick ,这确保了在非 constexpr 上下文中使用 constexpr 函数时出现链接错误。

这是我的看法:

#include <iostream>

struct Exc;

constexpr int foo( int a )
{
if( a == 42 )
{
throw Exc{};
}

return 666;
}


int main()
{
constexpr auto ret = foo(43);
std::cout << ret << "\n";

return ret;
}

但我无法让它工作(clang++ 3.8.1-23 和 g++ 6.3.0):

$ clang++ -std=c++14  main.cpp 
main.cpp:9:15: error: invalid use of incomplete type 'ExcBase'
throw ExcBase{};
^~~~~~~~~
main.cpp:3:8: note: forward declaration of 'ExcBase'
struct ExcBase;
^
1 error generated.

this thread中的一条评论建议另一个技巧:

#include <iostream>

constexpr int foo( int a )
{
if( a == 42 )
{
(void)reinterpret_cast<int>(a);
}

return 666;
}

int main()
{
constexpr auto ret = foo(43);
std::cout << ret << "\n";

return ret;
}

有效:没有错误或警告;当调用替换为 foo(42) 时,clang 返回:

$ clang++ -std=c++14 main.cpp 
main.cpp:19:20: error: constexpr variable 'ret' must be initialized by a constant expression
constexpr auto ret = foo(42);
^ ~~~~~~~
main.cpp:10:15: note: reinterpret_cast is not allowed in a constant expression
(void)reinterpret_cast<int>(a);
^
main.cpp:19:26: note: in call to 'foo(42)'
constexpr auto ret = foo(42);
^
1 error generated.

这太棒了。但 gcc 在这两种情况下都能愉快地编译代码。现在问题来了。 constexpr 函数如何以不能在非 constexpr 环境中使用的方式编写?

最佳答案

问题是您实际上实例化(调用构造函数)一个不完整类型的结构。您谈论的这个技巧需要任何在链接时找不到的符号。因此,您可以使用 int 而不是 struct:

http://coliru.stacked-crooked.com/a/3df5207827c8888c

#include <iostream>

extern int Exc;

constexpr int foo( int a )
{
if( a == 42 )
{
throw Exc;
}

return 666;
}


int main()
{
// Compiles
constexpr auto ret = foo(43);
std::cout << ret << "\n";

// This will show linker error as expected:
// /tmp/ccQfT6hd.o: In function `main':
// main.cpp:(.text.startup+0x4c): undefined reference to `Exc'
// collect2: error: ld returned 1 exit status
int nn;
std::cin >> nn;
auto ret2 = foo(nn);

return ret;
}

关于c++14 - 如何防止意外发出 constexpr 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44452717/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com