constexpr 생성자에서 배열을 초기화하는 것이 합법적입니까?


11

다음 코드는 합법입니까?

template <int N>
class foo {
public:
    constexpr foo()
    {
        for (int i = 0; i < N; ++i) {
            v_[i] = i;
        }
    }

private:
    int v_[N];
};

constexpr foo<5> bar;

Clang은 수락하지만 GCC 및 MSVC는 거부합니다.

GCC의 오류는 다음과 같습니다

main.cpp:15:18: error: 'constexpr foo<N>::foo() [with int N = 5]' called in a constant expression
   15 | constexpr foo<5> bar;
      |                  ^~~
main.cpp:4:15: note: 'constexpr foo<N>::foo() [with int N = 5]' is not usable as a 'constexpr' function because:
    4 |     constexpr foo()
      |               ^~~
main.cpp:4:15: error: member 'foo<5>::v_' must be initialized by mem-initializer in 'constexpr' constructor
main.cpp:12:9: note: declared here
   12 |     int v_[N];
      |         ^~

이런 종류의 코드가 정상이라면 index_sequences의 사용을 상당히 줄일 수 있습니다.


1
Gcc10도 받아들입니다.
songyuanyao

MSVC에서 오류를 기록 할 수 있습니까?
max66

... 그리고 GCC도.
평균

1
@songyuanyao-g ++ 10 컴파일 C ++ 20; C ++ 17 이상 컴파일을 거부합니다. 요점은 _vC ++ 17까지 초기화 목록에서 초기화 해야하는 것으로 보입니다 . 아마도 C ++ 20에서 뭔가 바뀌었을 것입니다.
max66

2
이 연타가 정적 스토리지 기간 객체가 좋아,이 객체가 기본-초기화되었을 수도 있습니다 "말을 제로로 가져옵니다의"인식 "을 사용하지만 읽 제안 할 수 있기 때문, 실제로 흥미로운 @Evg int멤버가 정의되지 않은 동작을하지 않습니다 ". 나는 GCC가 그것을 따르지 않는지 , 아니면 다른 방법 인지 궁금합니다 .
궤도에서 경량 경주

답변:


13

C ++ 20까지constexpr컨텍스트 에서는 간단한 기본 초기화가 금지되었습니다 .

필자가 추측 한 이유는 기본적으로 초기화 된 프리미티브, 프로그램에 정의되지 않은 동작을 제공하는 동작 및 정의되지 않은 동작이있는 표현식은 constexpr( ref ) 금지되어 있기 때문에 "우연히"읽을 수 있기 때문입니다 . 언어는 확장되었으므로 이제 컴파일러는 이러한 읽기가 발생하는지 확인해야하며 그렇지 않은 경우 기본 초기화를 승인해야합니다. 컴파일러에게는 약간 더 많은 작업이지만 프로그래머가 볼 수 있듯이 상당한 이점이 있습니다.

이 논문은 constexpr 컨텍스트에서 사소한 기본 구성 가능 유형에 대한 기본 초기화를 허용하면서 정의되지 않은 동작의 호출을 계속 허용하지 않습니다. 즉, 초기화되지 않은 값을 읽지 않는 한 힙 및 스택 할당 시나리오 모두에서 constexpr에서 이러한 상태를 허용해야합니다.

C ++ 20부터는 v_"초기화되지 않은" 상태로 두는 것이 합법적 입니다. 그런 다음 모든 요소 값을 할당했습니다.


4
@ max66 나도! 모든 나는 C ++ 위키 백과에 20 명 변경 목록을 스캔과 관련된 무언가를 발견했다 않았다 constexpr) 링크 된 제안 및 탈지
궤도의 밝기 경주

3
나쁜 부분은 C ++을 사용하는 20 년 이상이라는 것입니다. 매일 새로운 것을 배우면 ... 또는 나쁜 프로그래머이거나 C ++이 너무 복잡해집니다.
max66

5
@ max66 거의 후자입니다. 또한 2 년마다 근본적으로 변화하고 있다는 사실은 빠르게 변화하는 목표입니다. 누가 그걸 따라갈 수있어?! 심지어 컴파일러조차도이를 따르지 않습니다.
궤도에서 가벼움

@ max66이 백서가 떠 오릅니다 : Vasa를 기억하십시오!
EVG

@Evg 오, 그 종이가 (IRONY)를 지나갔습니다. 에 딱 맞다!
궤도의 가벼움
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.