【问题标题】:Compiling C++11 code on older versions of gcc在旧版本的 gcc 上编译 C++11 代码
【发布时间】:2020-01-18 13:18:49
【问题描述】:

我们正在尝试构建一个 C++ 项目,该项目最近被修改为在使用 gcc 4.5.4 的遗留系统上将一些析构函数标记为 noexcept。

使用这个编译器版本是强制的,所以升级不是解决办法。

代码中唯一的 C++11 特性是析构函数的 noexcept 说明符。

我已经读到,虽然 4.5 不支持标准 -std=c++11,但它确实支持(当时)实验标志 -std=gnu++0x 。但是,使用它来编译使用 noexcept 说明符的简单测试项目也不允许代码编译。此示例的代码如下所示。

test.h:

class Test
{
public:
    Test();
    ~Test() noexcept;
};

test.cpp:

#include "test.h"
#include <iostream>

using namespace std;

Test::Test()
{
  cout<<"Ctor"<<endl;
}

Test::~Test() noexcept
{
  cout<<"Dtor"<<endl;
}

main.cpp:

#include "test.h"

int main(int argc, char **argv)
{
 {
  Test t;
 }

 return 0;
}

我猜我使用的实验标志应该是这里的主要解决方案,但我想在这里检查一下是否可能缺少任何替代方案。

如果无法使用 gcc 4.5.4 编译此代码,我的解决方案是声明一个仅在特定条件下应用 noexcept 的宏,该条件仅在旧版构建系统上评估为 true。但我对替代品持开放态度。

顺便说一句,我在使用此编译器时遇到的错误是:

# g++ -std=c++0x test.cpp main.cpp -o runme
In file included from test.cpp:1:0:
test.h:5:17: error: expected ‘;’ before ‘noexcept’
test.cpp:11:15: error: expected initializer before ‘noexcept’
In file included from main.cpp:1:0:
test.h:5:17: error: expected ‘;’ before ‘noexcept’

【问题讨论】:

  • 你试过用-Dnoexcept=编译吗?这是我要尝试的第一件事。
  • 我会推荐-Dnoexcept=throw()
  • @JerryCoffin 可能适用于此示例,但由于 noexcept 运算符,一般情况下不适用。
  • @eerorika:至少根据问题,他们不使用 noexcept 运算符,只使用 noexcept 说明符:“代码中唯一的 C++11 功能是 noexcept 说明符析构函数。”

标签: c++ c++11 gcc


【解决方案1】:

编写可跨 C++ 方言移植的程序的一般解决方案,无论是针对不同的标准版本还是针对语言扩展,都是将该功能包装在一个宏中:

#if __cplusplus >= 201103L
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif

Test::~Test() NOEXCEPT

然而,析构函数是隐式的noexcept(除非子对象有一个潜在的抛出析构函数),所以在这种特殊情况下最简单的解决方案是简单地删除noexcept声明,因为这不会改变C++11 中的程序。

【讨论】:

  • 这是真的,但是将析构函数设置为 noexcept 引用如下:isocpp.github.io/CppCoreGuidelines/…
  • @andrei 请注意,cpp 核心指南通常不是要求。遵循指南是完全可选的。
  • 谢谢,我明白你的意思,我同意,我的意思是字面意义上的要求,即来自客户的明确形式。
  • @andrei 我明白了。我想这不是强制使用古代编译器的同一个客户端?强加相互矛盾的要求是相当不公平的。
猜你喜欢
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
  • 2013-02-19
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多