禁用MSVC的例外

时间:2010-11-13 20:43:05

标签: c++ visual-studio-2010 unit-testing exception-handling

我正在尝试在Visual Studio 2010中完全禁用异常,并确保禁用异常处理我有以下测试:

class CompilerFlagsTestExceptionConstructor
{
public:
 CompilerFlagsTestExceptionConstructor() { throw std::exception("Exceptions Enabled"); }
 ~CompilerFlagsTestExceptionConstructor() { }
};

class CompilerFlagsTests : public CPPUNIT_NS::TestFixture
{
 CPPUNIT_TEST_SUITE( CompilerFlagsTests );
  CPPUNIT_TEST( Test_NoExceptions );
 CPPUNIT_TEST_SUITE_END();
public:
 void Test_NoExceptions()
 {
  try
  {
   CompilerFlagsTestExceptionConstructor object;
  }
  catch(std::exception)
  {
   assert(!"Exceptions are enabled");
  }
 }
};

我已在属性页面中检查过禁用了异常处理,并且我还在所有项目中禁用了RTTI。我已经尝试将/ EH设置为负数,并从命令行中省略它。

每次运行此测试时,它都会失败并且正确抛出异常

我想要禁用异常处理的原因是因为目标软件是针对目标体系结构编写的,该体系结构本身不支持异常处理并导致大量代码膨胀以适应堆栈展开。目标体系结构还具有最大可执行文件大小,因此禁用异常会缩小代码并具有性能优势。我想在Windows版本上禁用异常处理,以确保对目标的错误处理正常。

我做错了吗?这个测试是否会起作用?是否有其他强制和测试方法可以禁用异常?

谢谢!

3 个答案:

答案 0 :(得分:2)

这不是/ EH所做的,它只是控制放松处理程序的排放。 / EHsc确保在可能引发C ++异常时调用析构函数,/ EHa确保为任何异常(包括SEH)调用它们。省略/ EH是你想要减少处理程序开销的,编译器省略了在堆栈分配的对象上调用析构函数的异常过滤器。将析构函数更改为:

~CompilerFlagsTestExceptionConstructor() { 
    assert(!"Something is wrong with /EH");
}

如果您想查找不需要的try / catch代码,那么您需要注意

  

警告C4530:使用了C ++异常处理程序,但未启用展开语义。指定/ EHsc

答案 1 :(得分:1)

/EHsc-应该这样做(至少它与msvc 14一样)

答案 2 :(得分:0)

我不确定你的测试是否有意义。如果禁用例外,该行为应该是什么?扔掉只是成为一个没有操作?这就是测试表明行为的原因。

我希望有用地禁用异常throw应该是编译错误,或者抛出异常禁用应该立即终止进程。

但这是一个题外话。 MSVC将为throw语法发出对_CxxThrowException的调用。如果我们定义我们自己的版本,我们就可以跳到我们的歌曲上了:

#include <windows.h>
#include <stdio.h>

extern "C"
void __stdcall _CxxThrowException(void * pObject,
    _s__ThrowInfo const * pObjectInfo)
{

  printf("Nope\n");
}

struct a
{ };

int main()
{
  try {
  throw a();
  } catch(const a&) {
    printf("Caught an exception\n");
  }
}

此程序打印出来

  

都能跟得上

当然,这些信息仅用于娱乐目的,并且与您正在执行此操作的上下文相匹配,以便与错误处理逻辑相匹配。我希望例如,您不打算将程序的Windows版本发送给这样的人。