我有一些Linux代码我试图在Windows中重复使用。我使用编译器并使用Qt 5.9.1进行安装,并且我使用googletest进行单元测试。在Linux下正常测试的是在Windows下中止。 (参见What is the cause of "This application has requested the Runtime to terminate it in an unusual way"?我知道它是如何中止的。)
工具版本信息:
将生成错误的简化代码:
- MyClass.h
#pragma once
class MyClass
{
public:
MyClass();
~MyClass();
void Func();
};
- MyClass.cpp
/*01*/ #include "MyClass.h"
/*02*/
/*03*/ #include <sstream>
/*04*/ #include <stdexcept>
/*05*/
/*06*/ namespace {
/*07*/ std::stringstream ss;
/*08*/ }
/*09*/
/*10*/ MyClass::MyClass() {}
/*11*/ MyClass::~MyClass() {}
/*12*/
/*13*/ void MyClass::Func() {
/*14*/ std::stringstream ss;
/*15*/ ss << "BOO!";
/*16*/ throw std::runtime_error( ss.str() );
/*17*/ //throw std::runtime_error( std::string( ss.str().c_str() ) );
/*18*/ //throw std::runtime_error( "BOO!" );
/*19*/ }
- MyClassTestSuite.cpp
#include <gtest/gtest.h>
#include <MyClass.h>
#include <stdexcept>
#include <iostream>
class MyClassTestSuite: public ::testing::Test
{
};
TEST_F( MyClassTestSuite, test_FuncThrows )
{
MyClass obj;
try
{
obj.Func();
FAIL();
}
catch( std::runtime_error & e ) {}
}
我得到的错误是:
This application has requested the Runtime to terminate it in an unusual way.
关于MyClass.cpp中注释掉的代码:
ss
成为用于创建异常的范围内变量不会产生错误。---更新------
当我创建一个main并在使用cmake的范围之外运行它时:
main.cpp中:
#include "MyClass.h"
#include <stdexcept>
#include <iostream>
int main( int, char** )
{
MyClass obj;
std::cout << "Calling\n";
try
{
obj.Func();
std::cout << "Call successful\n";
}
catch( const std::runtime_error & e )
{
std::cout << "Caught exception " << e.what() << "\n";
}
return 0;
}
输出:
C:\> i686-w64-mingw32-g++.exe MyClass.cpp main.cpp -o test.exe
C:\> test.exe
Calling
Caught exception BOO!
因此异常被正确抛出并被捕获。
我已经运行了ldd,而ldd给出的答案是,无效的独立主程序和无法运行的单元测试程序都具有完全相同的依赖关系链。
This post表明可能会有一些微软重写的东西是罪魁祸首。 (掌握很多吸管之一。)
- 奇怪------
MyClass::Func()
只会抛出。ss
成为基类的受保护成员,则派生类按预期运行(无错误)但从基类抛出会导致中止。 -O3
优化开关之前无法正常工作。我已尝试使用此库但它没有效果。这开始感觉像是编译器中的一个错误,但我怎么能证明这一点? (我的期望是,在试图证明它时,我找到了根本原因并且它不会成为编译器。编译器不会被扔进野外&#34; willy-nilly。)这个错误真的感觉就像变量在内存释放后被引用一样。
- 可能是罪魁祸首------
在阅读differences between SJLJ, SEH, and DW2后,我了解到有不同的异常类型(谁知道?不是我,直到5分钟前)和SEH是Windows喜欢的,特别是在64位计算机上。我怀疑这是我的问题,尽管我还没有证明这一点。我的工具链开发过程让我走上了一条道路,现在这应该是一个非问题,但这是我的帽子,所以下次我遇到这个问题我会知道在哪里检查。知道是战斗的一半......