假设我在共享库中有一个函数抛出了一些对象,并且有一个主要的可执行文件调用该函数并试图捕获该对象,例如
#ifndef DECL_H
#define DECL_H
void pitch();
struct MyException {
MyException();
MyException(const MyException&);
~MyException();
};
#endif
#include "decl.h"
MyException::MyException() {}
MyException::MyException(const MyException&) {}
MyException::~MyException() {}
void pitch() {
throw MyException();
}
#include <stdio.h>
#include "decl.h"
int main() {
try { pitch(); }
catch (MyException& e) { printf("MyException()\n"); }
catch (...) { printf("[unknown exception]\n"); }
}
all:
$(CXX) -shared -fPIC $(CXXFLAGS) $(LTO) pitch.cpp -o libpitch.so
$(CXX) -g $(CXXFLAGS) $(LTO) main.cpp -L. -lpitch
./a.out
如果我在不进行链接时优化的情况下进行编译,那么一切都很好:
CXXFLAGS="-g -O2" LTO="" make
c++ -shared -fPIC -g -O2 pitch.cpp -o libpitch.so
c++ -g -g -O2 main.cpp -L. -lpitch
./a.out
MyException()
但是一旦我打开链接时优化,就不再捕获抛出的对象:
CXXFLAGS="-g -O2" LTO="-flto" make
c++ -shared -fPIC -g -O2 -flto pitch.cpp -o libpitch.so
c++ -g -g -O2 -flto main.cpp -L. -lpitch
./a.out
[unknown exception]
这是预期的行为吗?这是我的C ++代码中的问题还是其他问题?这是在macOS 10.14.5上:
$ c++ -v
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
答案 0 :(得分:0)
这不是预期的行为。
我在Linux(ubuntu)上使用gcc 4.x,5.x,6.x,7.x和8.x以及clang 6.0对其进行了测试。 -O2 -flto
一切正常。
不幸的是,由于我无法复制它(我没有Mac),所以我无法告诉您出了什么问题,但这不是您的代码恕我直言。
编辑:
我不能很清楚地说您的代码“没有错”(尽管我按照您的说明进行了测试-但是,我需要将LD_LIBRARY_PATH="."
设置为./a.out
才能正常工作(所以也许您正在加载其他库?))而没有向您展示我如何编写以上代码:
// decl.h:
#pragma once
#include <exception>
void pitch();
struct MyException : public std::exception
{
};
// pitch.cpp:
#include "decl.h"
void pitch()
{
throw MyException();
}
// main.cpp:
#include "decl.h"
#include <iostream>
int main()
{
try
{
pitch();
}
catch (MyException const& e)
{
std::cout << "MyException(): " << e.what() << std::endl;
}
catch (...)
{
std::cerr << "[unknown exception]" << std::endl;
}
}