static_assert和constexpr到底是什么
2023-06-19 16:07:58
标签: permissive constexpr static_assert
项目中遇到一个情况,当使用find_package去引用Qt以后,编译失败了。
原因是Qt那会自动引入/permissive选项。编译时,有没有这个选项,会造成结果不同。
代码如下:
template static constexpr AVKTypeTag of()
{
if constexpr (std::is_same_v)
{
return {ID::nil};
}
else if constexpr (std::is_same_v)
{
return {ID::f32};
}
.....
else
{
#ifdef __APPLE__
#else
static_assert(false, "invalid
type");
#endif
}
}
constexpr本意是用来在编译时决定表达式的值,然后编译的时候就知道是用的哪个分支,在优化时,可以直接生成对应的代码。
但是并不是编译时,选择性编译,也就是说if里的表达式是真,并不代表不再编译else分支。
而上面代码明显是写成了这个意图,搞混了编译时和运行时。static_assert(false)
这种代码永远是错的。
那为撒去掉了苹果,在Windows上有时候能正确呢?
经测试,主要目前这个方法是在Template里,当/permissive有和没有时,会导致检查一致性区别。
没有/permissive时,这个模板没引用,编译完这代码(没语法错)过了,没有实际类型导致实例化模板。能过
有/permissive时,这个模板没引用,编译完这代码(没语法错)过了,但是一致性检查可能会导致进行实例化,编译错。
同样的,如果这个模板有引用的话,就算没有/permissive,一样会报错。
也就是证明了,permissive只是在模板情况下,碰巧隐藏了错误,但是这个代码100%是错的。
也就是说编译的语法分析是正确的,语义分析是错的,不同情况可能造成了根本没有进行语义分析。
static_assert和constexpr到底是什么
项目中遇到一个情况,当使用find_package去引用Qt以后,编译失败了。
原因是Qt那会自动引入/permissive选项。编译时,有没有这个选项,会造成结果不同。
代码如下:
template static constexpr AVKTypeTag of()
{
if constexpr (std::is_same_v)
{
return {ID::nil};
}
else if constexpr (std::is_same_v)
{
return {ID::f32};
}
.....
else
{
#ifdef __APPLE__
#else
static_assert(false, "invalid type");
#endif
}
}
constexpr本意是用来在编译时决定表达式的值,然后编译的时候就知道是用的哪个分支,在优化时,可以直接生成对应的代码。
但是并不是编译时,选择性编译,也就是说if里的表达式是真,并不代表不再编译else分支。
而上面代码明显是写成了这个意图,搞混了编译时和运行时。static_assert(false)
这种代码永远是错的。
那为撒去掉了苹果,在Windows上有时候能正确呢?
经测试,主要目前这个方法是在Template里,当/permissive有和没有时,会导致检查一致性区别。
没有/permissive时,这个模板没引用,编译完这代码(没语法错)过了,没有实际类型导致实例化模板。能过
有/permissive时,这个模板没引用,编译完这代码(没语法错)过了,但是一致性检查可能会导致进行实例化,编译错。
同样的,如果这个模板有引用的话,就算没有/permissive,一样会报错。
也就是证明了,permissive只是在模板情况下,碰巧隐藏了错误,但是这个代码100%是错的。
也就是说编译的语法分析是正确的,语义分析是错的,不同情况可能造成了根本没有进行语义分析。