dar*_*une 16 c++ static-assert compile-time c++17
假设我有以下简化程序:
#include <cassert>
struct Dimensions {
Dimensions& operator=(int i) {
assert(i != 0);
return *this;
}
};
int getDim();
int main() {
Dimensions dims;
dims = getDim();//ok, just use runtime assert
dims = 0;//compile error wanted here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在第一种情况(getDim)中,无法检查编译时,因此我们很高兴在运行时检查它。
但是在理论上看起来可行dims = 0;时,是否也可以通过某种方式检测到编译(对于第二种情况)?(甚至可能带有某种类型的重载或包装?)
使用gcc编译器在C中完成的一种典型方法,也将在C ++中工作:您可以使用__builtin_constant_pBuiltin来检查表达式是否被不断求值,然后检查该表达式,然后调用用__attribute__((__warning__))或声明的函数__attribute__((__error__))。像这样:
#include <cassert>
#include <type_traits>
#define CONCAT(a, b) a ## b
#define XCONCAT(a, b) CONCAT(a, b)
#define maybe_static_maybe_not_assert(expr) do { \
if (__builtin_constant_p(expr)) { \
if (!(expr)) { \
extern __attribute__((__warning__( \
"static_assert: expression: " #expr " will fail on runtime!" \
))) void XCONCAT(maybe_static_maybe_not_assert_warn, __LINE__)(); \
XCONCAT(maybe_static_maybe_not_assert_warn, __LINE__)(); \
} \
} \
assert(expr); \
} while(0)
struct Dimensions {
Dimensions& operator=(int i) {
maybe_static_maybe_not_assert(i != 0);
return *this;
}
};
int getDim();
int main() {
Dimensions dims;
dims = getDim();
dims = 0;
dims = 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用优化进行编译时,应发出警告:
In member function 'Dimensions& Dimensions::operator=(int)',
inlined from 'int main()' at <source>:32:12:
<source>:12:70: warning: call to 'maybe_static_maybe_not_assert_warn21' declared with attribute warning: static_assert: expression: i != 0 will fail on runtime! [-Wattribute-warning]
12 | XCONCAT(maybe_static_maybe_not_assert_warn, __LINE__)(); \
| ^
<source>:21:9: note: in expansion of macro 'maybe_static_maybe_not_assert'
21 | maybe_static_maybe_not_assert(i != 0);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 0
Run Code Online (Sandbox Code Playgroud)
这是_FORTIFY_SOURCE在glibc中实现的方法。
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |