在C++14中引入的更改可能会破坏用C++11编写的程序
What changes introduced in C++14 can potentially break a program written in C++11?
简介
随着C++14(又名C++1y(标准接近最终版本,程序员必须自问向后兼容性以及与之相关的问题。
问题
在对该问题的回答中,指出本标准有一个附录,专门用于说明修订之间的变更信息。
如果能够解释前面提到的附录中的这些潜在问题,也许可以借助与其中提到的内容相关的任何正式文件,这将是有益的。
- 根据标准:在C++14中引入的哪些更改可能会破坏用C++11编写的程序
注意:在这篇文章中,我认为断裂变化";属于或同时属于
CCD_ 1 1。当编译为C++14时,将使合法的C++11格式错误的更改,以及
CCD_ 2 2。当编译为C++14时,与C++11相比,将更改运行时行为的更改
C++11与C++14,标准怎么说
标准草案(n3797(有一节专门针对这类信息,其中描述了标准的一个修订版和另一个修订版本之间的(潜在的(差异。
这篇文章使用了[diff.cpp11]
这一部分,作为半详细讨论的基础,讨论可能影响为C++11编写但编译为C++14的代码的更改。
C.3.1]数字分隔符
引入数字分隔符是为了以更可读的方式编写数字文字,并像往常一样(在代码之外(编写。
int x = 10000000; // (1)
int y = 10'000'000; // (2), C++14
很容易看出,在上面的代码段中,(2(比
有关此功能的潜在问题是,单引号在C++11中总是表示字符文字的开始/结束,但在C++14,单引号可以围绕字符文字2(。
示例代码段,在C++11和C++14中都是合法的,但具有不同的行为
#define M(x, ...) __VA_ARGS__
int a[] = { M(1'2, 3'4, 5) };
// int a[] = { 5 }; <-- C++11
// int a[] = { 3'4, 5 }; <-- C++14
// ^-- semantically equivalent to `{ 34, 5 }`
(注意:有关单引号作为数字分隔符的更多信息,请参阅n3781.pdf(
C.3.2]规模交易
C++14引入了声明operator delete
的全局过载的机会,该全局过载适用于大小的释放,这在C++11中是不可能的。
然而,该标准还规定,开发人员不能只声明下面两个相关函数中的一个,必须声明none或both;在[new.delete.single]p11.中说明
void operator delete (void*) noexcept;
void operator delete (void*, std::size_t) noexcept; // sized deallocation
关于潜在问题的进一步信息:
重新定义全局无大小版本的现有程序也不会定义大小版本。当实现引入大小版本,替换将不完整,很可能程序将调用上提供大小的解除定位器的实现用程序员提供的分配器分配的对象。
注意:报价取自n3536-C++规模的经销商
(注:更多感兴趣的内容可在题为n3536-C++规模的交易,作者Lawrence Crowl(
C.3.3]constexpr
成员函数,不再隐式const
在C++14中,constexpr有很多变化,但唯一会改变C++11和C++14之间语义的变化是标记为constexpr的成员函数的constants。
这一更改背后的基本原理是允许constexpr成员函数对其所属的对象进行变异,这是由于constexpr的放宽而允许的。
struct A { constexpr int func (); };
// struct A { constexpr int func () const; }; <-- C++11
// struct A { constexpr int func (); }; <-- C++14
关于这一变化的推荐材料,以及为什么它足够重要,可以引入潜在的代码破坏:
- Andrzej的C++博客-"constexpr"函数不是"const">
- open-std.org.-constexpr成员函数和隐式const
- (open-std.org/strong>-放宽对constexpr函数的约束(
示例代码段,在C++11和C++14中都是合法的,但具有不同的行为
struct Obj {
constexpr int func (int) {
return 1;
}
constexpr int func (float) const {
return 2;
}
};
Obj const a = {};
int const x = a.func (123);
// int const x = 1; <-- C++11
// int const x = 2; <-- C++14
C.3.4]std::gets
的移除
std::gets
已从标准库中删除,因为它被认为是危险的。
当然,这意味着试图在C++14中编译为C++11编写的代码,其中使用了这样的函数,很可能会编译失败。
(注意:有一些编写代码的方法不会编译失败,并且具有不同的行为,这取决于从标准库中删除std::gets
(
- Qt creator 4.11,在应用程序输出面板中创建一个链接
- 在Visual Studio中单实例Qt应用程序版本5.11.1中,在所有其他窗口的顶部打开Qt MainWindow
- 如何获得CMake Tools以在Visual Studio Code中编译具有C++11(或更高版本)功能的程序?
- 多线程 C++11 应用程序中的同步
- 为什么在 Direct X 11 中没有我的程序输出?
- 当程序预期根据用户输入再次循环时,它会导致分段错误:11
- 将C++11程序链接到CMake中的Qt5会导致错误
- 错误在Windows上使用Clang编译C 11程序
- 调试 DirectX 11 程序时缺少 DLL (d3dx11d_43.dll)
- 编译一个相当简单的c++11程序时,gcc和clang之间的结果不同
- C++11程序可以使用BlueZ吗?
- 非C++11程序中的C++11代码/库
- 为什么下面c++11程序崩溃visual studio 2013 express edition
- c++11程序能在任何CPU上工作吗?
- 如何解决 DirectX 11 程序中"unresolved external symbol"错误?
- 为较旧的Linux编译c++ 11程序
- 是否有表达式为"C++11"的有效 C++11 程序?
- 在多线程c++ 11程序中,当异常未处理时会发生什么
- 简单的DirectX 11程序运行时错误
- clang++只在删除-std=c++11选项时使用boost::format编译c++11程序