Program Tip

C ++ 14에 도입 된 어떤 변경으로 인해 C ++ 11로 작성된 프로그램이 잠재적으로 중단 될 수 있습니까?

programtip 2020. 12. 9. 21:39
반응형

C ++ 14에 도입 된 어떤 변경으로 인해 C ++ 11로 작성된 프로그램이 잠재적으로 중단 될 수 있습니까?


소개

C ++ 14 (일명 C ++ 1y ) 표준이 최종 상태에 가까워 지면 프로그래머는 이전 버전과의 호환성 및 이와 관련된 문제에 대해 자문해야합니다.


질문

이 질문에 대한 답변 에서 표준에는 개정 간의 변경 사항에 관한 정보 전용 부록 이 있다고 명시되어 있습니다.

앞서 언급 한 부록 에서 이러한 잠재적 문제를 설명 할 수 있다면 여기에 언급 된 내용과 관련된 공식 문서의 도움을 받아 도움이 될 것입니다.

  • 표준에 따르면 : C ++ 14에 도입 된 어떤 변경 사항 이 C ++ 11로 작성된 프로그램을 잠재적으로 중단시킬 수 있습니까?

참고 :이 게시물에서는 " 주요 변경 사항 "을 다음 중 하나 또는 둘 다로 간주합니다 .
1. 법적 만들 것입니다 변화 C ++를 11 로 컴파일 할 때 잘못 형성된 C ++ (14) 와;
2. C ++ 14C ++ 11 로 컴파일 될 때 런타임 동작을 변경하는 변경 .


C ++ 11 vs C ++ 14 , 표준은 무엇을 말합니까?

표준 초안 ( n3797 )에는 이러한 종류의 정보 전용 섹션이 있으며, 여기서는 표준 개정판과 다른 개정판 간의 차이점을 설명합니다.

이 게시물은 C ++ 11[diff.cpp11] 용으로 작성 되었지만 C ++ 14 로 컴파일 된 코드에 영향을 미칠 수있는 변경 사항에 대한 약간의 정교한 토론의 기반으로 해당 섹션을 사용했습니다 .


C.3.1] 숫자 구분자

더 읽기 쉬운 방식으로 숫자 리터럴을 작성하고 더 자연스러운 방식으로 분할 할 수 있도록 숫자 구분 기호가 도입되었습니다.

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

그것은 있는지 쉽게 (2) 보다 훨씬 더 쉽게 읽을 수있다 (1) 모두 초기화가 같은 값을 가질 때, 위의 코드에서.

이 기능과 관련된 잠재적 인 문제는 작은 따옴표가 항상 C ++ 11 에서 문자 리터럴 의 시작 / 끝을 나타내지 만 C ++ 14 에서는 작은 따옴표character-literal을 둘러싸 거나 사용될 수 있다는 것입니다. 이전에 표시된 방식으로 (2) .


예제 스 니펫, C ++ 11C ++ 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 ++ 14C ++ 11 에서는 불가능했던 크기 할당 해제operator delete적합한 글로벌 오버로드를 선언 할 기회를 제공합니다 .

그러나 표준은 또한 개발자가 아래의 두 관련 함수 중 하나만 선언 할 수 없으며 none 또는 둘 다 선언해야한다고 요구합니다 . [new.delete.single] p11에 명시되어 있습니다.

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


잠재적 인 문제에 대한 추가 정보 :

크기가 지정되지 않은 전역 버전을 재정의하는 기존 프로그램도 크기 지정 버전을 정의하지 않습니다. 구현에서 크기가 지정된 버전을 도입하면 대체가 불완전하며 프로그램이 프로그래머가 제공 한 할당 자로 할당 된 개체에 대해 구현에서 제공 한 크기 할당 해제자를 호출 할 가능성이 있습니다.

참고 : n3536 에서 가져온 견적 -C ++ 크기 할당 해제

(참고 : Lawrence Crowl이 작성한 n3536-C ++ Sized Deallocation 이라는 제목의 논문에서 더 많은 관심을 끌 수 있습니다. )


C.3.3] constexpr멤버 함수, 더 이상 암시 적으로const

C ++ 14에서 constexpr대한 많은 변경 사항이 있지만 C ++ 11C ++ 14 간에 의미 체계를 변경하는 유일한 변경 사항 constexpr 로 표시된 멤버 함수상수 입니다 .

이 변경의 근거는 constexpr 멤버 함수 가 자신이 속한 객체를 변경하도록 허용하는 것입니다. 이는 constexpr완화 로 인해 허용 됩니다.

struct A { constexpr int func (); };

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


이 변경 사항에 대한 권장 자료 및 잠재적 인 코드 손상을 도입 할만큼 중요한 이유 :


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 )

참고URL : https://stackoverflow.com/questions/23980929/what-changes-introduced-in-c14-can-potentially-break-a-program-written-in-c1

반응형