C++14 中引入的哪些更改可能会破坏用 C++11 编写的程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23980929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What changes introduced in C++14 can potentially break a program written in C++11?
提问by Filip Roséen - refp
Introduction
介绍
With the C++14(aka. C++1y) Standard in a state close to being final, programmers must ask themselves about backwards compatibility, and issues related to such.
随着C++14(又名C++1y)标准接近最终版本,程序员必须自问向后兼容性以及与此相关的问题。
The question
问题
In the answers of this questionit is stated that the Standard has an Appendixdedicated to information regarding changes between revisions.
在对这个问题的回答中指出,该标准有一个附录,专门介绍有关修订之间变化的信息。
It would be helpful if these potential issues in the previously mentioned Appendixcould be explained, perhaps with the help of any formal documents related to what is mentioned there.
如果可以解释前面提到的附录中的这些潜在问题,可能会得到与那里提到的内容相关的任何正式文件的帮助,这将是有帮助的。
- According to the Standard: What changes introduced in C++14can potentially break a program written in C++11?
- 根据标准:C++14 中引入的哪些更改可能会破坏用 C++11 编写的程序?
回答by Filip Roséen - refp
Note: In this post I consider a "breaking change" to be either, or both, of;
1. a change that will make legal C++11ill-formed when compiled as C++14, and;
2. a change that will change the runtime behavior when compiled as C++14, vs C++11.
注意:在这篇文章中,我认为“重大更改”是其中之一,或两者兼而有之;
1.编译为C++14时会使合法的C++11格式错误的更改,以及;2. 编译为C++14与C++11时将改变运行时行为的更改。
C++11vs C++14, what does the Standard say?
C++11vs C++14,标准怎么说?
The Standard draft (n3797) has a section dedicated for just this kind of information, where it describes the (potentially breaking) differences between one revision of the standard, and another.
标准草案 ( n3797) 有一个部分专门用于提供此类信息,其中描述了标准的一个修订版与另一个修订版之间的(潜在破坏性)差异。
This post has used that section, [diff.cpp11]
, as a base for a semi-elaborate discussion regarding the changes that could affect code written for C++11, but compiled as C++14.
这篇文章使用了该部分,[diff.cpp11]
作为关于可能影响为C++11编写但编译为C++14 的代码的更改的半详细讨论的基础。
C.3.1] Digit Separators
C.3.1] 数字分隔符
The digit separator was introduced so that one could, in a more readable manner, write numeric literals and split them up in a way that is more natural way.
引入了数字分隔符,以便人们可以以更易读的方式编写数字文字并以更自然的方式将它们拆分。
int x = 10000000; // (1)
int y = 10'000'000; // (2), C++14
It's easy to see that (2)is much easier to read than (1)in the above snippet, while both initializers have the same value.
很容易看出上面代码片段中的(2)比(1)更容易阅读,而两个初始值设定项都具有相同的值。
The potential issue regarding this feature is that the single-quotealways denoted the start/end of a character-literalin C++11, but in C++14a single-quotecan either be surrounding a character-literal, or used in the previously shown manner (2).
关于此功能的潜在问题是,单引号在C++11 中始终表示字符文字的开始/结束,但在C++14 中,单引号可以包围字符文字,也可以使用以前面所示的方式(2)。
Example Snippet, legal in both C++11and C++14, but with different behavior.
示例代码段,在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 }`
( Note: More information regarding single-quotesas digit separators can be found in n3781.pdf)
(注意:有关单引号作为数字分隔符的更多信息可以在n3781.pdf 中找到)
C.3.2] Sized Deallocation
C.3.2] 大小释放
C++14introduces the opportunity to declare a global overload of operator delete
suitable for sized deallocation, something which wasn't possible in C++11.
C++14引入了声明operator delete
适合大小释放的全局重载的机会,这在C++11 中是不可能的。
However, the Standard also mandates that a developer cannot declare just one of the two related functions below, it must declare either none, or both; which is stated in [new.delete.single]p11.
但是,该标准还要求开发人员不能仅声明以下两个相关函数之一,它必须声明none或两者都声明;这在[new.delete.single]p11 中有说明。
void operator delete (void*) noexcept;
void operator delete (void*, std::size_t) noexcept; // sized deallocation
Further information regarding the potential problem:
有关潜在问题的更多信息:
Existing programs that redefine the global unsized version do not also define the sized version. When an implementation introduces a sized version, the replacement would be incomplete and it is likely that programs would call the implementation-provided sized deallocator on objects allocated with the programmer-provided allocator.
Note: Quote taken from n3536 - C++ Sized Deallocation
重新定义全局无大小版本的现有程序也不会定义大小版本。当实现引入了大小版本时,替换将是不完整的,并且程序很可能会在使用程序员提供的分配器分配的对象上调用实现提供的大小释放器。
( Note: More of interest is available in the paper titled n3536 - C++ Sized Deallocation, written by Lawrence Crowl)
(注意:在Lawrence Crowl撰写的题为n3536 - C++ Sized Deallocation的论文中可以找到更多有趣的内容)
C.3.3] constexpr
member-functions, no longer implicitly const
C.3.3]constexpr
成员函数,不再隐式const
There are many changes to constexprin C++14, but the only change that will change semantics between C++11, and C++14is the constantnessof a member-functionmarked as constexpr.
C++14 中constexpr有很多变化,但唯一会改变C++11和C++14之间语义的变化是标记为constexpr的成员函数的常量性。
The rationale behind this change is to allow constexprmember-functionsto mutate the object to which they belong, something which is allowed due to the relaxation of constexpr.
这种变化背后的基本原理是允许constexpr成员函数改变它们所属的对象,这是由于constexpr的放松而被允许的。
struct A { constexpr int func (); };
// struct A { constexpr int func () const; }; <-- C++11
// struct A { constexpr int func (); }; <-- C++14
Recommended material on this change, and why it is important enough to introduce potential code-breakage:
关于此更改的推荐材料,以及为什么它足够重要以引入潜在的代码破坏:
- Andrzej's C++ blog- “constexpr” function is not “const”
- open-std.org- constexpr member functions and implicit const
- (open-std.org- Relaxing constraints on constexpr functions)
- Andrzej 的 C++ 博客——“constexpr”函数不是“const”
- open-std.org- constexpr 成员函数和隐式 const
- (open-std.org- 放宽对 constexpr 函数的约束)
Example snippet, legal in both C++11and C++14, but with different behavior
示例片段,在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] Removal of std::gets
C.3.4] 删除 std::gets
std::gets
has been removedfrom the Standard Library because it is considered dangerous.
The implications of this is of course that trying to compile code written for C++11, in C++14, where such a function is used will most likely just fail to compile.
这当然意味着尝试编译为 C++11 编写的代码,在 C++14 中使用这样的函数很可能会编译失败。
( Note: there are ways of writing codethat doesn't fail to compile, and have different behavior, that depends on the removal of std::gets
from the Standard Library)
(注意:有一些编写代码的方法不会编译失败,并且有不同的行为,这取决于std::gets
从标准库中删除)