使用 -O2 或 -O3 标志编译时未捕获异常

Exception not caught when compiled with -O2 or -O3 flag

本文关键字:捕获异常 编译 标志 -O2 -O3 使用      更新时间:2023-10-16

我在使用 -O2 或 -O3 标志编译下面的 GCC 示例时遇到了问题。

#include <string>
#include <stdexcept>
#include <iostream>
class Args {
    public:
        Args(int, char** argv);
        const std::string get_arg() const;
    private:
        int argc_;
        int index_ = 0;
        char** argv_;
};
Args::Args(int argc, char** argv):
    argc_(argc),
    argv_(argv)
{
}
const std::string Args::get_arg() const
{
    if (index_ >= argc_) {
        throw std::out_of_range("Out of range.");
    }
    return std::string(argv_[index_]);
}
int main(int, char** argv)
{
    Args args(0, argv);
    try {
        std::string a = args.get_arg(); // Must throw.
        std::cout << "After get_arg(): " << a << std::endl;
    } catch(std::out_of_range) {
        std::cout << "Catched" << std::endl;
    }
    return 0;
}

使用 -O3 标志编译示例时

g++ -std=c++11 -Wall -pedantic -Wextra -O3 -g0 -o args args.cpp

异常std::out_of_range未在捕获块中捕获。输出为

terminate called after throwing an instance of 'std::out_of_range'
  what():  Out of range.
Abort trap

如果示例使用没有 -O2 或 -O3 的 GCC 编译,则一切正常

g++ -std=c++11 -Wall -pedantic -Wextra -g0 -o args args.cpp

或与 CLang 一起

clang++ -std=c++11 -Wall -pedantic -Wextra -O3 -g0 -o args args.cpp
clang++ -std=c++11 -Wall -pedantic -Wextra -g0 -o args args.cpp

GCC 版本: (FreeBSD Ports Collection) 5.4.0
CLang版本:4.0.0
操作系统: FreeBSD 11.1 (amd64)

错误在哪里?

感谢您的导航。我在这篇文章中找到了正确的解决方案 https://stackoverflow.com/a/33279425/8838989。当示例使用标志编译时,它有效-Wl,-rpath=/usr/local/lib/gcc5

g++5 -std=c++11 -Wall -pedantic -Wextra -O3 -g0 -Wl,-rpath=/usr/local/lib/gcc5 -o args args.cpp