Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何制作我的C++;编译器发出一个constexpr值(例如,在警告中?)_C++_Compiler Warnings_Constexpr - Fatal编程技术网

C++ 如何制作我的C++;编译器发出一个constexpr值(例如,在警告中?)

C++ 如何制作我的C++;编译器发出一个constexpr值(例如,在警告中?),c++,compiler-warnings,constexpr,C++,Compiler Warnings,Constexpr,(这有点像是个玩笑,但请耐心听我说。) 我收到了一条关于班次太多的警告。现在,为了诊断这个问题,我希望我的编译器以某种方式发出constexpr值,该值用作移位量 到目前为止,我所做的是尝试用一个数字参数实例化一个类型,我知道我可以将其放置在范围之外,然后添加我想要的constexpr值,得到一个显示总和的错误。但这是一个丑陋的黑客。有没有一种方法可以将constexpr值(希望不仅仅是整数)发送到标准错误流?e、 g.连同一些解释性文字或警告信息 我问的是GCC 6.x及更高版本和clang

(这有点像是个玩笑,但请耐心听我说。)

我收到了一条关于班次太多的警告。现在,为了诊断这个问题,我希望我的编译器以某种方式发出
constexpr
值,该值用作移位量

到目前为止,我所做的是尝试用一个数字参数实例化一个类型,我知道我可以将其放置在范围之外,然后添加我想要的constexpr值,得到一个显示总和的错误。但这是一个丑陋的黑客。有没有一种方法可以将constexpr值(希望不仅仅是整数)发送到标准错误流?e、 g.连同一些解释性文字或警告信息


我问的是GCC 6.x及更高版本和clang 4.x及更高版本。

好吧,显而易见的方法与您所说的类似——让编译器在发出诊断时提及该值

constexpr int I = 8 % 3;

template<int i>
class TheValueYouWantIs { static_assert(i != i); };


int main() {
    TheValueYouWantIs<I>();
}
constexpr int I=8%3;
模板
将您想要的值分类为{static_assert(i!=i);};
int main(){
Youwantis()的值;
}
因此:

prog.cpp:class TheValueYouWantIs'实例化中:
进度cpp:8:27:从这里开始需要
[…信息量较少的东西…]

警告显然更依赖于编译器,但应该很容易实现。不过,这种方法对字符数组没有帮助。这不是一个完整的解决方案。

这非常难看,但会以一种可识别但糟糕的格式生成表达式的名称及其值:

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);
}
constexpr int I=8%3;
#定义连接(s1,s2)s1##s2
#定义扩展然后连接(s1,s2)连接(s1,s2)
模板
在_previous _error _具有{static _assert(i!=i,“”);}值的_中,对名为_的_表达式_进行初始化;
#定义错误\u打印(\u expr)\
展开然后连接(在下一个错误中找到表达式的值)\
_previous_error_中名为_的_表达式_具有_value();
int main(){
打印错误(I);
}
这将产生(使用GCC 6):

main.cpp:在函数“int main()”中:
main.cpp:11:25:error:'In_the_next_error_you_will_find_该表达式的_值_未在此范围内声明
展开然后连接(在下一个错误中找到表达式的值)\
^
main.cpp:3:45:注:在宏“连接”的定义中
#定义连接(s1,s2)s1##s2
^
main.cpp:11:1:注意:在宏的展开中“展开然后连接”
展开然后连接(在下一个错误中找到表达式的值)\
^
main.cpp:15:5:注意:在宏“ERROR\u PRINT”的展开中
打印错误(I);
^
main.cpp:在实例化“类中的\u表达式\u在\u中命名的\u之前的\u错误\u具有\u值”时:
main.cpp:15:5:从这里开始需要
main.cpp:7:61:错误:静态断言失败:
在_previous _error _具有{static _assert(i!=i,“”);}值的_中,对名为_的_表达式_进行初始化;

但是我相信这可以通过一些constexpr字符串技巧得到极大的改进。

GCC displays
你能告诉我们你认为什么是丑陋的黑客吗?@路人:这基本上是斯奈夫特尔写的。@hvd:思考模板。
静态断言(I!=I)
格式不正确,应该用类似于
静态断言的东西来代替(始终为假::值)
@Jarod42足够公平。不过,我不知道有哪位编译器在第一阶段会不厌其烦地抱怨这个问题。@Pezo-不,问题是编译器不必实例化模板来抱怨。这使得练习毫无意义。@Pezo Jarod的观点是,即使在看到tem之前,编译器也可以自由地抱怨它模板实例化,仅仅是因为
i
的任何值都无法使其通过断言。这就是为什么我没有使用,比如说,
static\u assert(false)
。因此,实际上,
static\u assert
需要一个额外的
,“
,但除此之外,这与我所拥有的非常相似(除了我对现有的模板类型进行了标记).请看下面我可怕的回答,了解另一个拙劣的伎俩。
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);
}
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, ""); };
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>(); }
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>(); }