2017-12-13 2 views
1

Vulkan 및 Visual Studio 2017을 사용하는 렌더링 엔진에서 작업 중이며 최근 다음과 같은 유형의 문제가 발생했습니다.Visual Studio에서 constexpr 표현식에 관한 컴파일 문제 20130

템플릿 구조체가 template<uint32_t id> struct A;입니다. 이 구조체는 별도의 헤더 파일에 id=0, ... , N-1에 대해 정의됩니다. 정의 중 일부는 B 구조체에 대해 static constexpr std::array<B, M(id)> member이고 id에 따라 숫자는 M입니다. 나는 주어진 값으로 b 타입이 B 인 constexpr 함수 (그리고 도우미 함수)가 b과 같은 배열의 몇개 요소를 포함하는지 계산한다.

도우미 기능 :

template<size_t Size> 
constexpr void count_in_array(B b, const std::array<B, Size>& a, uint32_t& count) 
{ 
    for(auto& e : a) 
    { 
     if(e==b) 
      ++count; 
    } 
} 

주요 기능 :

template<uint32_t... ids> 
constexpr uint32_t count_in_arrays(B b, std::index_sequence<ids...>) 
{ 
    uint32_t count=0; 
    auto l ={ (count_in_array(b, A<ids>::member, count), 0)... }; 
    return count; 
} 

내가 컴파일, 나는 C1001 내부 컴파일러 오류는 다음과 같이 보입니다. 이상한 것은 변수 constexpr

constexpr uint32_t var=count_in_arrays(b, std::make_index_sequence<N>()); 

(A constexpr B b에 대한)를 정의하기 위해 내가 그들을 사용하는 경우 때문에 내 함수들이 그냥이 작동한다는 것입니다, 그리고 내가 계산 된 (그리고 올바른)를 참조하십시오, 그 변수 위에 마우스를 후버 나타나는 직사각형의 숫자.

필자는 컴파일러 스위치에 익숙하지 않아 위의 기능들에 대해서만 #pragma optimize("", on/off)을 사용하려했지만 도움이되지 않았습니다. 누군가 내 코드를 컴파일하기 위해 Visual Studio를 만드는 방법을 알고 있습니까?

비고 : 여기서는 struct B이 중요하지 않다고 확신합니다. 제 경우에는 내장 된 변수가 들어있는 간단한 데이터 구조체입니다.

+0

내부 컴파일러 오류는 항상 컴파일러의 버그입니다. 그래서 당신의'struct B'조차도 중요 할 수 있습니다. [MCVE] (https://stackoverflow.com/help/mcve)를 만들면 컴파일러 오류가 발생하고 MSVC에보고 할 수 있습니다. –

+0

예, 컴파일러가 코드를 거부하더라도 (예 : 일부 새로운 기능을 지원하지 않기 때문에), ICE하지 않아야합니다. 내가 한 가지 제안하고자하는 것은 프로젝트 설정 (프로젝트 -> 속성, C/C++ -> 언어로 이동하여 "C++ 언어 표준"을 C++ 17 또는 최신 버전으로 설정하는 것입니다.)이 문제를 해결할 것인지 모르겠습니다. 적어도 유익한 진단 정보를 줄 수는 있습니다 – SoronelHaetir

+0

MCVE가 무엇인지 모르겠습니다 (링크 덕분에), 제가 확인하고 있습니다. – Sandor

답변

1

먼저 내부 컴파일러 오류는 이고 항상 컴파일러 버그입니다. 이것을 MSVC에보고하십시오.

둘째,이 구현은 약간 이상합니다. constexpr 함수를 작성할 때보다 기능 지향적 인 방식으로 생각하고 싶습니다 - 입력 전용 인수, 출력 전용 결과. - 카운트를 반환 count

template <size_t Size> 
constexpr uint32_t count_in_array(B b, const std::array<B, Size>& a) 
{ 
    uint32_t count = 0; 
    for(auto& e : a) 
    { 
     if(e==b) 
      ++count; 
    } 
    return count; 
} 

이 좀 더 합리적인 구현 : count_in_array 반드시 단지 수를 반환해야합니다. 그뿐만 아니라 정말로 멋지게 구성됩니다. 어떻게 모든 것을 얻을 수 있습니까? 합계 :

template <size_t... Ids> 
constexpr uint32_t count_in_arrays(B b, std::index_sequence<Ids...>) 
{ 
    return (count_in_array(b, A<Ids>::member) + ...); 
} 

훨씬 명확합니다. 나는 접이식 표현은 아직 MSVC에서 꽤 일을 생각하면서,


주 (힘 soon은?하지만), 그 자체로 다른이를 구현하는 이유는 없습니다. 단지 수동으로 합계해야 함을 의미합니다. 즉, count_in_array()은 카운트를 반환하지 않아야합니다.

+0

접힌 표현식에 대해 알고 있지만 작성한대로 MSVC에서 아직 지원되지 않으며 내가 작성한 구현이 가장 짧고 자체적으로 구현 된 것처럼 보입니다. ,하지만 당신이 제안한 구현을 시도해 볼 것 같아요. 내게 이상하게 들릴지 모르겠어요. – Sandor

+0

@Sandor 그것은 이상한 것이 아니며 단지 버그 일뿐입니다. 코드가 잘못되었음을 암시하는 컴파일러 오류가 아닙니다. 소프트웨어에 버그가 있습니다. 심지어 comp ... –

+0

좋아, 알았다. 이 사실을 MSVC에보고하는 방법을 확인하겠습니다. 모두에게 감사드립니다! – Sandor

관련 문제