통합 또는 통합 유사 클래스에 대해 기본 생성자가 삭제되는 이유는 무엇입니까?

잭 X
struct A{
    A(){}
};
union C{
   A a;
   int b = 0;
};
int main(){
    C c;
}

위의 코드에서 GCC와 Clang은 모두 공용체의 기본 생성자 C가 삭제 된 것으로 정의되어 있다고 불평합니다 .

그러나 관련 규칙은 다음과 같이 말합니다.

클래스 X의 기본 생성자는 다음과 같은 경우 삭제 된 것으로 정의됩니다.

  • X는 중요하지 않은 기본 생성자가있는 변형 멤버가 있고 X의 변형 멤버에는 기본 멤버 이니셜 라이저가없는 공용체입니다 .
  • X는 중요하지 않은 기본 생성자가있는 변형 멤버 M이 있고 M을 포함하는 익명 공용체의 변형 멤버에는 기본 멤버 initializer 가없는 비 조합 클래스입니다 .

강조된 문구에 주목하십시오. IIUC 예제에서 변형 멤버 b에는 기본 멤버 이니셜 라이저가 있으므로 기본 기본 생성자는 삭제 된 것으로 정의되어서는 안됩니다. 이러한 컴파일러가이 코드를 잘못된 형식으로보고하는 이유는 무엇입니까?

정의를 다음 C으로 변경하면

union C{
   A a{};
   int b;
};

그러면 모든 컴파일러 가이 코드를 컴파일 할 수 있습니다. 이 동작은 규칙이 실제로 의미하는 바를 암시합니다.

X가 아닌 사소한 기본 생성자와 변형 부재에 대한 공급 초기화없이 기본 구성원이 노동 조합이다 변형 구성원을

이것이 컴파일러 버그입니까, 아니면 그 규칙의 모호한 표현입니까?

ecatmur

이것은 CWG 2084 를 통해 C ++ 14와 C ++ 17 사이에서 변경되었으며 , 이는 (모든) 공용체 멤버의 NSDMI가 기본 기본 생성자를 복원 할 수 있도록 허용하는 언어를 추가했습니다.

CWG 2084와 함께 제공되는 예는 귀하와 미묘하게 다릅니다.

struct S {
  S();
};
union U {
  S s{};
} u;

여기서 NSDMI는 중요하지 않은 멤버에있는 반면 C ++ 17에 채택 된 문구는 모든 멤버 의 NSDMI가 기본 생성자를 복원 할 수 있도록합니다 . DR에 기록 된대로

NSDMI는 기본적으로 mem-initializer의 구문 설탕입니다.

즉, NSDMI on int b = 0;은 기본적으로 mem-initializer 및 빈 본문을 사용하여 생성자를 작성하는 것과 같습니다.

C() : b{/*but use copy-initialization*/ 0} {}

옆으로, 그 보장 원칙으로 최대 노조의 한 변형 멤버는 NSDMI 약간의 절에 숨겨져있다 class.union.anon :

4-[...] Union의 Variant 멤버는 기본 멤버 이니셜 라이저를 가질 수 있습니다.

내 가정은 gcc와 Clang이 이미 위 (중요하지 않은 공용체 멤버의 NSDMI)를 허용했기 때문에 완전한 C ++ 17 지원을 위해 구현을 변경해야한다는 것을 깨닫지 못했다는 것입니다.

이것은 2016 년에 std-discussion 목록에서 논의되었으며 , 귀하와 매우 유사한 예가 있습니다.

struct S {
    S();
};
union U {
    S s;
    int i = 1;
} u;

결론은 clang과 gcc가 거부에 결함이 있다는 것입니다. 당시에는 오해의 소지가있는 메모가 있었지만 결과적으로 수정 되었습니다.

Clang의 경우 버그는 https://bugs.llvm.org/show_bug.cgi?id=39686 이며 변형 멤버 N3690 / N4140 대 N4659 / N4727로 인해 삭제 된 암시 적으로 정의 된 생성자 에서 SO로 다시 돌아 갑니다 . gcc에 해당하는 버그를 찾을 수 없습니다.

참고 MSVC가 제대로 수용 하고,이 초기화 c.b = 0있다, dcl.init.aggr 당 올바른 :

5-[...] 집계가 공용체이고 이니셜 라이저 목록이 비어 있으면

  • 5.4-변형 멤버에 기본 멤버 이니셜 라이저가있는 경우 해당 멤버는 기본 멤버 이니셜 라이저에서 초기화됩니다. [...]

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

C ++는 순수 가상 클래스에 대해 기본 "생성자 / 소멸자 / 복사 생성자 / 복사 할당 연산자"를 생성합니까?

분류에서Dev

파생 클래스 생성자에서 예외가 발생합니다. 기본 클래스 소멸자가 호출되지만 파생 클래스 소멸자가 아닌 이유는 무엇입니까?

분류에서Dev

이 유형 클래스 인스턴스가 통합에 실패한 이유는 무엇입니까?

분류에서Dev

사용자 지정 비동기 HTTP 처리기가 IIS 7.5 통합 모드에서만 오류 500을 생성합니다. 이유는 무엇입니까?

분류에서Dev

Python의 C3 MRO가 공통 기본 클래스에 의존하는 이유는 무엇입니까?

분류에서Dev

JavaScript 생성자에 기능을 추가하지 않고 대신 프로토 타입을 통해 추가해야하는 이유는 무엇입니까?

분류에서Dev

Facebook 공유 대화 상자를 내 웹 사이트에 통합하는 방법은 무엇입니까?

분류에서Dev

for 루프가 함수를 통해 숫자를 생성하는 데 사용되는 이유는 무엇입니까?

분류에서Dev

이동 시맨틱이있는 RAII 클래스에서 기본 생성자는 무엇을해야합니까?

분류에서Dev

이동 시맨틱이있는 RAII 클래스에서 기본 생성자는 무엇을해야합니까?

분류에서Dev

이동 시맨틱이있는 RAII 클래스에서 기본 생성자는 무엇을해야합니까?

분류에서Dev

기본 클래스에 대한 포인터를 통해 새 멤버가없는 파생 클래스 삭제

분류에서Dev

std :: throw_with_nested는 Exception의 가상 기본 클래스에 대한 기본 생성자를 예상합니까?

분류에서Dev

super ()를 사용하여 기본 클래스 생성자에 액세스해야하는 이유는 무엇입니까?

분류에서Dev

Spring을 통해 log4j2.xml을로드하면 log4j1 클래스에 대해 NoClassDefFoundError가 발생하는 이유는 무엇입니까?

분류에서Dev

내 기본 클래스의 정적 생성자가 호출되지 않는 이유는 무엇입니까?

분류에서Dev

모든 기본 클래스 생성자가 호출되지 않는 이유는 무엇입니까?

분류에서Dev

인라인 사용자 제공 생성자가 기본 클래스 생성자를 odr- 사용하는 이유는 무엇입니까?

분류에서Dev

ASM을 통해 생성 된 클래스의 생성자에 액세스하는 모든 리플렉션 메서드는 클래스가 기본 유형을 참조하는 경우 NoClassDefFoundError를 발생시킵니다.

분류에서Dev

"= default"대신 기본 생성자 "{}"를 사용하는 성능 차이가있는 이유는 무엇입니까?

분류에서Dev

내 통합 테스트가 get에 실패하는 이유는 무엇입니까? "ArgumentError : 잘못된 인수 (예상되는 URI 개체 또는 URI 문자열)"

분류에서Dev

Windows가 인텔 통합 그래픽에 대해 RAM을 정적으로 할당하지 않는 이유는 무엇입니까?

분류에서Dev

"이 클래스에는 기본 생성자가 있어야합니다."[Android]

분류에서Dev

기본 클래스 생성자가 값을 설정하지 않는 이유는 무엇입니까?

분류에서Dev

기본 클래스에 대한 기본 복사 및 이동 ctor 및 할당을 삭제하는 이유는 무엇입니까?

분류에서Dev

각 루프에 대해 기본 클래스 유형 또는 파생 클래스 유형 사용

분류에서Dev

사용자 정의보기 속성을 통해 스타일을 전달할 때 텍스트가 굵게 표시되지 않는 이유는 무엇입니까?

분류에서Dev

sqlplus 코드에서 복합 기본 키에 대해 ORA-00936 오류가 발생하는 이유는 무엇입니까?

분류에서Dev

처리 또는 대기를 통해 Ajax로 양식을 제출하고 서버 측에서 유효성을 검사합니다.

Related 관련 기사

  1. 1

    C ++는 순수 가상 클래스에 대해 기본 "생성자 / 소멸자 / 복사 생성자 / 복사 할당 연산자"를 생성합니까?

  2. 2

    파생 클래스 생성자에서 예외가 발생합니다. 기본 클래스 소멸자가 호출되지만 파생 클래스 소멸자가 아닌 이유는 무엇입니까?

  3. 3

    이 유형 클래스 인스턴스가 통합에 실패한 이유는 무엇입니까?

  4. 4

    사용자 지정 비동기 HTTP 처리기가 IIS 7.5 통합 모드에서만 오류 500을 생성합니다. 이유는 무엇입니까?

  5. 5

    Python의 C3 MRO가 공통 기본 클래스에 의존하는 이유는 무엇입니까?

  6. 6

    JavaScript 생성자에 기능을 추가하지 않고 대신 프로토 타입을 통해 추가해야하는 이유는 무엇입니까?

  7. 7

    Facebook 공유 대화 상자를 내 웹 사이트에 통합하는 방법은 무엇입니까?

  8. 8

    for 루프가 함수를 통해 숫자를 생성하는 데 사용되는 이유는 무엇입니까?

  9. 9

    이동 시맨틱이있는 RAII 클래스에서 기본 생성자는 무엇을해야합니까?

  10. 10

    이동 시맨틱이있는 RAII 클래스에서 기본 생성자는 무엇을해야합니까?

  11. 11

    이동 시맨틱이있는 RAII 클래스에서 기본 생성자는 무엇을해야합니까?

  12. 12

    기본 클래스에 대한 포인터를 통해 새 멤버가없는 파생 클래스 삭제

  13. 13

    std :: throw_with_nested는 Exception의 가상 기본 클래스에 대한 기본 생성자를 예상합니까?

  14. 14

    super ()를 사용하여 기본 클래스 생성자에 액세스해야하는 이유는 무엇입니까?

  15. 15

    Spring을 통해 log4j2.xml을로드하면 log4j1 클래스에 대해 NoClassDefFoundError가 발생하는 이유는 무엇입니까?

  16. 16

    내 기본 클래스의 정적 생성자가 호출되지 않는 이유는 무엇입니까?

  17. 17

    모든 기본 클래스 생성자가 호출되지 않는 이유는 무엇입니까?

  18. 18

    인라인 사용자 제공 생성자가 기본 클래스 생성자를 odr- 사용하는 이유는 무엇입니까?

  19. 19

    ASM을 통해 생성 된 클래스의 생성자에 액세스하는 모든 리플렉션 메서드는 클래스가 기본 유형을 참조하는 경우 NoClassDefFoundError를 발생시킵니다.

  20. 20

    "= default"대신 기본 생성자 "{}"를 사용하는 성능 차이가있는 이유는 무엇입니까?

  21. 21

    내 통합 테스트가 get에 실패하는 이유는 무엇입니까? "ArgumentError : 잘못된 인수 (예상되는 URI 개체 또는 URI 문자열)"

  22. 22

    Windows가 인텔 통합 그래픽에 대해 RAM을 정적으로 할당하지 않는 이유는 무엇입니까?

  23. 23

    "이 클래스에는 기본 생성자가 있어야합니다."[Android]

  24. 24

    기본 클래스 생성자가 값을 설정하지 않는 이유는 무엇입니까?

  25. 25

    기본 클래스에 대한 기본 복사 및 이동 ctor 및 할당을 삭제하는 이유는 무엇입니까?

  26. 26

    각 루프에 대해 기본 클래스 유형 또는 파생 클래스 유형 사용

  27. 27

    사용자 정의보기 속성을 통해 스타일을 전달할 때 텍스트가 굵게 표시되지 않는 이유는 무엇입니까?

  28. 28

    sqlplus 코드에서 복합 기본 키에 대해 ORA-00936 오류가 발생하는 이유는 무엇입니까?

  29. 29

    처리 또는 대기를 통해 Ajax로 양식을 제출하고 서버 측에서 유효성을 검사합니다.

뜨겁다태그

보관