如何使我的C 编译器发出constexpr值(例如警告?)

How to make my C++ compiler emit a constexpr value (e.g. in warning?)

本文关键字:警告 我的 何使 编译器 constexpr      更新时间:2023-10-16

(这是一个XY问题,但请携带我。)

我会收到有关轮班数量太大的汇编警告。现在,为了诊断这一点,我希望我的编译器以某种方式发出用作换档数量的constexpr值。

到目前为止,我这样做的方式是尝试实例化具有数字参数的类型,我知道我可以将其放置在范围之外,然后添加我想要的constexpr值并获得一个错误,向我显示了总和。但这是一个丑陋的黑客。是否有一种方法可以使ConstexPR值(希望不仅是整数)发出到标准错误流?例如以及一些解释性文字或警告消息?

我询问有关GCC 6.x的及以后的问题,然后再叮当4.x,然后再询问。

好吧,明显的方法与您所说的相似 - 使编译器在发出诊断时提及该值。

constexpr int I = 8 % 3;
template<int i>
class TheValueYouWantIs { static_assert(i != i); };

int main() {
    TheValueYouWantIs<I>();
}

因此:

prog.cpp: In instantiation of ‘class TheValueYouWantIs<2>’:
prog.cpp:8:27:   required from here
[...less informative stuff...]

警告显然更依赖编译器,但应该很容易。不过,这种事情对您的char阵列无济于事。不是一个完整的解决方案。

gcc显示 <<的操作数时,它在恒定表达式中发出错误消息时会显示出错误消息。当结果不用用作恒定表达式时,它不会显示<<的操作数。您可以通过添加一个原本毫无意义的常数来利用它。

template <int> constexpr int f() { return 1; }
template <int> constexpr int g() { return 40; }
template <int I> constexpr int h() { return f<I>() << g<I>(); }
int main() { h<1234>(); }

这会引起警告,而没有有关问题值的信息: warning: left shift count >= width of type [-Wshift-count-overflow]

template <int> constexpr int f() { return 1; }
template <int> constexpr int g() { return 40; }
template <int I> constexpr int h() { constexpr int i = f<I>() << g<I>(); return f<I>() << g<I>(); }
int main() { h<1234>(); }

这会导致有关问题值的信息(以及更多警告)的错误: error: right operand of shift expression ‘(1 << 40)’ is >= than the precision of the left operand

如果仅第二操作数是一个恒定的表达式,那么它仍然可以,因为此特定警告足以将左操作数变成常数1

这是超级态度的,但在可辨别的格式(

)中产生了表达式的名称及其值
constexpr int I = 8 % 3;
#define CONCATENATE( s1, s2 )               s1 ## s2
#define EXPAND_THEN_CONCATENATE( s1, s2 )   CONCATENATE( s1, s2 )
template<int i>
class The_expression_named_in_the_previous_error_has_value{ static_assert(i != i, ""); };

#define ERROR_PRINT(_expr) 
EXPAND_THEN_CONCATENATE(In_the_next_error_you_will_find_the_value_of_the_expression__, _expr); 
The_expression_named_in_the_previous_error_has_value<I>();
int main() {
    ERROR_PRINT(I);
}

这会产生(使用GCC 6):

main.cpp: In function ‘int main()’:
main.cpp:11:25: error: ‘In_the_next_error_you_will_find_the_value_of_the_expression__I’ was not declared in this scope
 EXPAND_THEN_CONCATENATE(In_the_next_error_you_will_find_the_value_of_the_expression__, _expr); 
                         ^
main.cpp:3:45: note: in definition of macro ‘CONCATENATE’
 #define CONCATENATE( s1, s2 )               s1 ## s2
                                             ^
main.cpp:11:1: note: in expansion of macro ‘EXPAND_THEN_CONCATENATE’
 EXPAND_THEN_CONCATENATE(In_the_next_error_you_will_find_the_value_of_the_expression__, _expr); 
 ^
main.cpp:15:5: note: in expansion of macro ‘ERROR_PRINT’
     ERROR_PRINT(I);
     ^
main.cpp: In instantiation of ‘class The_expression_named_in_the_previous_error_has_value<2>’:
main.cpp:15:5:   required from here
main.cpp:7:61: error: static assertion failed: 
 class The_expression_named_in_the_previous_error_has_value{ static_assert(i != i, ""); };

,但我敢肯定,这可以通过一些constexpr-string-trickery进行大规模改进。

相关文章: