C ++ 14中引入的更改可能会破坏使用C ++ 11编写的程序? [英] What changes introduced in C++14 can potentially break a program written in C++11?

查看:248
本文介绍了C ++ 14中引入的更改可能会破坏使用C ++ 11编写的程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介



使用 C ++ 14 (aka。 C ++ 1y )标准在接近最终的状态,程序员必须问自己关于向后兼容性和与此有关的问题。






问题



这个问题表示标准中有一个 专用于修订之间变更的信息。



如果可以解释前面提到的附录中的这些潜在问题,也许可以借助于与此处提到的内容相关的任何正式文档。




  • 根据标准 C ++ 14中引入的更改可能会破坏使用C ++ 11编写的程序?


解决方案


注意: post我认为一个打破更改


1.编译为 C ++ 14 时会导致合法 C ++ 11 变化的更改;

2。在编译为 C ++ 14 ,vs C ++ 11 时,会改变运行时行为。


< blockquote>




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)比上述代码段中的(1)更容易阅读,而两个初始值设定器的值相同。



有关此功能的潜在问题是单引号始终表示 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
// ^在语义上等同于{34,5}`

(注意:有关单引号作为数字分隔符的详细信息,请参见 n3781.pdf






C.3.2 ] Sized Deallocation



C ++ 14 引入了声明全局重载 operator delete 适用于大小的解除分配,这在 C ++ 11 中是不可能的



,该标准还规定开发人员不能仅声明以下两个相关函数中的一个,它必须声明两者;

  void operator delete(void * )noexcept; 
void operator delete(void *,std :: size_t)noexcept; // size deallocation




有关潜在问题的进一步信息:



重新定义全局未定义版本的现有程序不b $ b定义大小的版本。当实现引入大小为
的版本时,替换将是不完整的,并且很可能
程序将调用由程序员提供的分配器分配的
对象上的实现提供的大小的解除分配器。 / p>

注意:引用自 n3536 - C ++大小交易分配



(注意:更多的兴趣可以在 n3536 - C ++ Sized Deallocation ,由Lawrence Crowl编写)






C .3.3] constexpr 成员函数,不再隐含 const



C ++ 14中的 constexpr 有许多变化,但是只有改变了 C ++ 11 C ++之间的语义14 是标记为 constexpr 成员函数常数

此更改的基本原理是允许 constexpr 成员函数改变他们所属的对象,这是由于缩减 constexpr

  struct A {constexpr int func(); }; 

// struct A {constexpr int func()const; }; < - C ++ 11
// struct A {constexpr int func(); }; < - C ++ 14




关于此更改的推荐材料,以及为什么引入潜在的代码中断程度至关重要:








示例代码片段在 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






3.4]移除 std :: gets



std :: gets 已经从标准库中移除,因为它被认为危险



这意味着尝试编译代码对于C ++ 11,在C ++ 14中,使用这样的函数很可能只是无法编译。






(注意:有些方法可以编写代码,但编译失败,并且有不同的行为,这取决于从标准库中移除 std :: gets


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.


The question

In the answers of this question it is stated that the Standard has an Appendix dedicated to information regarding changes between revisions.

It would be helpful if these potential issues in the previously mentioned Appendix could 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++14 can potentially break a program written in C++11?

解决方案

Note: In this post I consider a "breaking change" to be either, or both, of;
1. a change that will make legal C++11 ill-formed when compiled as C++14, and;
2. a change that will change the runtime behavior when compiled as C++14, vs C++11.


C++11 vs C++14, what does the Standard say?

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.

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.


C.3.1] Digit Separators

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.

The potential issue regarding this feature is that the single-quote always denoted the start/end of a character-literal in C++11, but in C++14 a single-quote can either be surrounding a character-literal, or used in the previously shown manner (2).


Example Snippet, legal in both C++11 and C++14, but with different behavior.

#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-quotes as digit separators can be found in n3781.pdf )


C.3.2] Sized Deallocation

C++14 introduces the opportunity to declare a global overload of operator delete suitable for sized deallocation, something which wasn't possible in 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.

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 )


C.3.3] constexpr member-functions, no longer implicitly const

There are many changes to constexpr in C++14, but the only change that will change semantics between C++11, and C++14 is the constantness of a member-function marked as constexpr.

The rationale behind this change is to allow constexpr member-functions to mutate the object to which they belong, something which is allowed due to the relaxation of 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:


Example snippet, legal in both C++11 and C++14, but with different behavior

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

std::gets has been removed from 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.


( Note: there are ways of writing code that doesn't fail to compile, and have different behavior, that depends on the removal of std::gets from the Standard Library )

这篇关于C ++ 14中引入的更改可能会破坏使用C ++ 11编写的程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆