【发布时间】:2021-04-23 22:33:36
【问题描述】:
尝试在命令行中使用 vcvarsall.bat 编译以下代码会引发警告,指出代码中需要异常处理程序,但在使用 /EHsc 之前未调用。
代码:
#include <iostream>
int main()
{
std::cout << "hello world" << std::endl;
return 0;
}
批处理文件:
@echo off
cl C:\Development\..\basicmath.cpp
警告:
C:\...\ostream(746): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
C:...\basicmath.cpp(10): note: see reference to function template instantiation 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)' being compiled
ostream 第 746 行的第 743 - 754 行(来自错误)是 _TRY:
if (!_Ok) {
_State |= ios_base::badbit;
} else { // state okay, insert
_TRY_IO_BEGIN
if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) {
for (; 0 < _Pad; --_Pad) { // pad on left
if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) {
_State |= ios_base::badbit; // insertion failed, quit
break;
}
}
}
将 /EHsc 添加到我的批处理文件将允许它运行,但我想知道这是为什么。 为什么输出文件中的这段代码需要调用 EHsc?
MSDOCS 说 EHsc 用于清理以防止内存泄漏,是什么导致了泄漏,为什么他们需要外部程序来修复泄漏而不是在同一个文件中修复它(这听起来可能很粗鲁,但它只是无知)?
编辑:感谢您指出它是警告而不是错误。
【问题讨论】:
-
注意:这不是错误,而是警告。它不会阻止编译成功,除非您有
/WX选项(将警告视为错误)。我必须说,如果编译器的开发人员首先将行为 A 定义为默认行为,然后建议将其更改为行为 B,这似乎是一个奇怪的决定,这样会更好。我想这一定是有原因的。一个 TL;DR 的答案真的是——在所有项目的编译选项中添加/EHs(或/EHsc),你就可以忘记这个话题了。 -
感谢您指出这是一个警告而不是错误,我什至没有注意到它仍然可以很好地创建我的
.exe并且运行没有问题。如果没有成功,我会非常专注。 -
默认情况下
cl不会为标准 C++ 编译。它编译为支持(除其他外)SEH(Microsoft 特有的结构化异常处理方法)和堆栈展开(异常在调用堆栈上传播时发生的情况)的特定于 Microsoft 的方言。<iostream>中的某些函数会引发 C++ 异常。/EHsc中的s启用与 C++ 标准要求一致的堆栈展开。c指示编译器假定extern "C"函数不会抛出。当 IDE 在后台使用cl编译 C++ 时,通常默认启用这些选项。 -
有趣,如果我理解,我可能不会,cl 是 vcvarsall.bat 的一部分,所以如果我使用不同的编译器,它不会使用 cl 并且默认情况下会有 eh?
-
@BornGeek - 据我了解,默认情况下支持 SEH - 如果您的代码仅使用 SEH 而没有 C++ 异常,它将起作用。它与需要启用的标准 C++ 的要求一致的堆栈展开(假设您有可能引发 C++ 异常的代码 -
<iostream>就是这种情况 - iostreams 默认情况下不会引发异常,但改变它是可能在运行时)。
标签: c++ exception compiler-errors