What changes made in C ++ 14 could potentially break a program written in C ++ 11?

Introduction

In the C ++ 14 standard (aka. C ++ 1y), in a state close to final, programmers should ask themselves backward compatibility and problems associated with such.




Question

The answers to this question indicate that the Standard has an Application dedicated to information on changes between versions.

It would be helpful if these potential problems in the aforementioned Appendix could be explained, possibly with the help of any official documents related to what is mentioned there.

  • According to the standard: what changes made in C ++ 14 could potentially break the program written in C ++ 11?
+60
c ++ language-lawyer c ++ 11 c ++ 14
Jun 01 '14 at 2:34
source share
1 answer

Note In this post, I believe that the “change interrupt” should be either one or both of these:
1. A change that makes legitimate C ++ 11 poorly formed when compiling C ++ 14 and;
2. a change that will change the runtime behavior when compiling C ++ 14, vs C ++ 11.




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

The standard draft ( n3797 ) has a section devoted only to such information, where it describes the (potentially violating) differences between one version of the standard and another.

This post used this section [diff.cpp11] as the basis for a semi- [diff.cpp11] discussion of changes that might affect code written for C ++ 11 but compiled as C ++ 14.




C.3.1] Digital dividers

The number separator was introduced in such a way that it is possible to write numerical literals in a more readable way and separate them in such a way that this is a more natural way.

 int x = 10000000; // (1) int y = 10'000'000; // (2), C++14 

It is easy to see that (2) is much easier to read than (1) in the above snippet, while both initializers have the same meaning.

A potential problem with this function is that a single quote always indicates the beginning / end of a character literal in C ++ 11, but in C ++ 14, a single quote can either surround an alphabetic character, or is used in the previously shown way (2).


An example fragment that is legal in both C ++ 11 and C ++ 14, but with a 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: For more information on single quotes as delimiters, see n3781.pdf )




C.3.2] Exemption amount

C ++ 14 provides the ability to declare a global operator delete overload suitable for the release size, which was not possible in C ++ 11.

However, the standard also provides that a developer cannot declare only one of the two related functions below, he must declare either none , or how ; which is specified in [new.delete.single] p11.

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


Additional information about a potential problem:

Existing programs that override the global version without modification also do not determine the size of the version. When the implementation enters the version size, the replacement will be incomplete, and it is likely that the programs will refer to the release objects allocated by the programmable allocator.

Note : Quote taken from n3536 - C ++ Extended Release

(Note: There is more interest in a document called n3536 - C ++ Sized Deallocation , written by Lawrence Crowle)




C.3.3] constexpr functions, already implicitly const

There are many changes to constexpr in C ++ 14, but the only change that will change the semantics between C ++ 11 and C ++ 14 is the constancy of the member function labeled constexpr.

The rationale for this change is to allow constexpr members to mutate the object to which they belong, something that is allowed due to constexpr relaxation .

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


Recommended material about this change, and why it is important enough to introduce a potential code breakdown:


Fragment example, legal in both C ++ 11 and C ++ 14, but with a 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] Removing std::gets

std::gets been removed from the standard library because it is considered dangerous .

The consequence of this is, of course, an attempt to compile code written for C ++ 11 in C ++ 14, where such a function is used, most likely, it just does not compile.


(Note: there are ways to write code that cannot be compiled and have different behavior, which depends on removing std::gets from the standard library)

+227
Jun 01 '14 at 2:34
source share
— -



All Articles