2016-08-10 1 views
9

constexpr 컴파일 타임에 평가할 수있는 표현식을 컴파일 타임에 평가할 수 있습니다.constexpr을 기본값으로 사용할 수없는 이유는 무엇입니까?

이 키워드가 필요한 이유는 무엇입니까? 가능하다면 컴파일러가 모든 표현식을 컴파일 타임에 평가하도록 허용하거나 요구하지 않는 이유는 무엇입니까?

표준 라이브러리에는 constexpr을 불균등하게 적용하여 많은 불편을 겪습니다. constexpr을 "기본"으로 설정하면이 문제를 해결하고 방대한 양의 기존 코드를 개선 할 수 있습니다.

+0

함수, 변수 또는 둘 다를 의미합니까? – aschepler

+8

기록을 위해, 나는 가까운 투표에 동의하지 않습니다. 문제는 이것이 수행 될 수없는 기술적 인 이유를 묻는 것입니다. 기존의 대답은 어떤 의견도없이 그러한 답을줍니다. –

답변

1

참고 : 아래 내용에도 불구하고 constexpr을 기본값으로 만드는 것에 대해 좋아합니다. 하지만 아직 완성되지 않은 이유를 묻는 질문에 대답하기 위해 mattnewport의 마지막 코멘트에 대해 간단하게 설명하겠습니다 :

오늘 상황을 고려하십시오. 상수 표현식이 필요한 컨텍스트에서 표준 라이브러리의 일부 함수를 사용하려고합니다. constexpr로 표시되지 않으므로 컴파일러 오류가 발생합니다. 이 작업을 위해 변경해야 할 것은 "명확하게"유일한 정의는 constexpr이라는 단어를 정의에 추가하는 것입니다.

이제 우리가 제안을 채택한 대체 우주에서의 삶을 고려해보십시오. 이제 코드가 컴파일됩니다.내년에는 작업중인 프로젝트에 Windows 지원을 추가하기로 결정했습니다. 얼마나 힘들 수 있습니까? Windows 사용자는 Visual Studio를 사용하여 컴파일하고 다른 모든 사용자는 gcc를 계속 사용하게됩니까?

처음으로 Windows에서 컴파일하려고하면 컴파일러 오류가 발생합니다.이 함수는 상수 표현 컨텍스트에서 사용할 수 없습니다. 문제의 코드를보고 gcc와 함께 제공되는 버전과 비교하십시오. 그것들은 약간 다르며 gcc와 함께 제공되는 버전은 단순한 사고로 인해 constexpr에 대한 기술적 요구 사항을 충족하며 Visual Studio와 함께 제공되는 것과 마찬가지로 다시 깎인 사고로 이러한 요구 사항을 충족시키지 못합니다. 이제 뭐?

아무 문제는 없지만 Microsoft에 버그 보고서를 제출할 것입니다.이 기능은 수정되어야합니다. 여러분의 버그 리포트를 닫습니다 : 표준은 결코이 함수가 상수 표현에서 사용 가능해야한다는 것을 절대로 말하지 않으므로 우리가 원하는대로 구현할 수 있습니다. 그래서 gcc 관리자에게 버그 보고서를 제출합니다. 왜 내가 이식성이없는 코드를 사용하고 있다고 경고하지 않았습니까? 그리고 그들은 그것도 닫습니다 : 그것이 휴대용이 아니라는 것을 어떻게 알았습니까? 다른 사람들이 표준 라이브러리를 어떻게 구현하는지 추적 할 수는 없습니다.

이제 어떻게 되나요? 아무도 정말 잘못한 일은 없었습니다. gcc 여러분이나 Visual Studio 사용자가 아니라 여러분이 아닙니다. 그러나 여전히 이식성이 떨어지는 코드로 끝나며이 시점에서 행복한 캠프가 아닙니다. 다른 모든 것이 평등하다면, 좋은 언어 표준은이 상황을 가능한 한 불가능하게 만들려고 노력할 것입니다.

다른 컴파일러 예제를 사용했지만 동일한 컴파일러의 최신 버전으로 업그레이드하거나 다른 설정으로 컴파일하려고 할 때도 마찬가지입니다. 예 : 함수에 유효한 인수를 사용하여 호출되는지 확인하는 assert 문이 포함되어 있습니다. 어설 션을 사용하지 않고 컴파일하면 어설 션이 "사라지고"함수가 constexpr에 대한 규칙을 충족합니다. 어설 션을 활성화하면 해당 어설 션이 충족되지 않습니다. (constexpr에 대한 규칙이 매우 관대하지만 C++ 11 규칙에 따라 더 큰 문제였던 요즘은 요즘에도 그럴 가능성이 적지 만 원칙적으로 요점은 여전히 ​​남아 있습니다.)

마지막으로 우리는 분명히 알 수 있습니다 사소한 문제의 오류 메시지. 오늘날의 세계에서 constexpr 함수의 cout 문을 사용하려고하면 바로 간단한 오류가 발생합니다. 여러분의 세계에서 우리는 템플리트를 사용하는 것과 동일한 상황을 경험하게 될 것입니다. 깊은 스택 추적은 출력 스트림 구현의 맨 아래까지 계속됩니다. 치명적이지는 않지만 반드시 성가시다.

1 년 6 개월이 지났지 만 여전히 도움이되기를 바랍니다.

+0

이것은 지금까지 처음으로 유용한 대답입니다. 특정 함수에 대해 컴파일 타임에 평가할 수 있는지 여부는 표준에서 지정한 요구 사항을 벗어난 구현에 따라 달라진다는 응답을 통해 말합니다. 따라서 표준 라이브러리 구현을 전환하면 프로그램이 중단 될 수 있습니다. –

+0

한편, constexpr이 될 수있는 모든 함수는 부작용이없고 함수 인수에만 의존하는 등의 특정 특성을 공유합니다.이 정보는 모든 표준 라이브러리 함수에 대한 표준에서 정의 된 함수 인터페이스 사양에서 사용할 수 있습니다 .Soooo - constexpr이 될 수있는 모든 기능을 실제로 constexpr로 만드는 것은 문제가 될 것이라고 생각하지 않습니다. 나는 constexpr 키워드가 실제로 함수 구현이 실제로 constexpr이되고 강제적으로 구문 오류가 발생하지 않도록 강제하는 역할을 추가한다고 덧붙였다. –

+0

re : 의역 : 예, 이제 알았습니다. 다시 : 첫 번째 유용한 답변 : 듣기 좋게. 나는 실제로 mattnewport의 마지막 몇 발언을 듣고 그가 "portable"라는 단어를 암시하려고하는 모든 것을 명시했다. "나는 constexpr이 될 수있는 모든 기능을 실제로 constexpr이 문제가 될 것이라고 생각하지 않는다"고 생각합니다. 너무 공격적이라고 생각합니다. 예를 들어 삼각 함수를 생각해보십시오. 그들의 사양은 아마도 요구 사항을 충족시킵니다. (나는 확인하지 않았다.) 그러나 대부분의 구현이 그들을 만나는 것은 의심 스럽다. 모든 사람들이 자신의 삼각 함수를 다시 쓰라고 주장하고 싶습니까? –

15

컴파일 타임에 as-if 규칙에 따라 부작용이없는 계산을 평가할 수 있습니다. 무엇 constexpr

는 호환 컴파일러가 1 컴파일 시간 계산 가능한 표현을 감지 할 요구되는 데이터 흐름 분석에 보증을 제공하고, 또한 그들이 얻을 수 있도록 프로그래머가 그 의도를 표현할 수있다 실수로 사전 계산할 수없는 일을하는 경우 진단.

constexpr을 기본값으로 설정하면 매우 유용한 진단 기능이 제거됩니다. 검출 "가능하면이"중단 문제를 해결해야하기 때문에 "컴파일시 가능한 경우에 모든 식을 평가 필요"일반적으로


1

는 비 선발하고, 컴퓨터 과학자들은이 것을 알고 일반적인 경우에는 불가능합니다. 따라서 출력이 { "compile-time에서 계산 가능", "컴파일시 에서 계산할 수 없거나을 결정할 수 없음"} 인 경우에는 이완을 사용합니다. 그리고 다른 컴파일러가 결정할 수있는 능력은 테스트가 얼마나 똑똑한가에 달려 있는데, 이는이 기능을 이식 할 수 없게 만듭니다. constexpr은 사용할 정확한 테스트를 정의합니다. 현명한 컴파일러는 표준 테스트 지시보다 더 많은 표현식을 미리 계산할 수 있지만 테스트에 실패하면 constexpr으로 표시 할 수 없습니다.

+1

'constexpr'조차도 명시 적으로 질문의 일부는 아니지만 컴파일 타임 컨텍스트 (예 : 템플릿 인수)에서 평가할 때를 제외하고는 컴파일 타임 평가를 보장하지 않는다는 점에 유의할 가치가 있습니다. –

+0

@KyleStrand : 표준에서 컴파일러가'constexpr' 객체를 초기화하는 데 사용 된 표현식이 표준에서 정의 된 규칙에 따라 사전 계산 될 수 있음을 감지해야한다고 말하는 것은 맞습니다. 항상 그렇게하는 것은 아닙니다. –

+3

'constexpr' * 강제 컴파일 타임 평가와 같은 잘못된 생각에 근거하여 원래 질문에 대한 잘못된 대답을 쉽게 상상할 수 있기 때문에이 점을 언급합니다. –

1

Ben Voigt가 지적했듯이, 컴파일러는 이미 as-if 규칙에 따라 컴파일 타임에 아무 것도 평가할 수 없습니다.

컴파일 시간 상수가 인 곳에서 사용할 수있는 표현식에 대한 명확한 규칙은입니다. 그건 내가 같이 코드를 작성하고 휴대용 될 것입니다 알 수 있습니다 의미 : 당신이 이식이를 지정하고 것들 프로그래머에 유용한 진단을 제공 할 수있는 방법을 모르겠어요 표준에서 키워드와 명확한 규칙없이

constexpr int square(int x) { return x * x; } 

... 
int a[square(4)] = {}; 
... 

constexpr으로되어 있지만 요구 사항을 충족하지 못합니다.

+0

"이 이식 가능 방법을 어떻게 지정할 수 있을지 모르겠다 ..."- 컴파일러가 현재 constexpr이 올바르게 사용되는지 여부를 결정하는 것과 같은 방법입니다. 진단 프로그램은 이미 구현되었습니다. 그러나 constexpr으로 표시된 표현식에만 적용됩니다. 나는 컴파일 타임에 호출되는 표현식에 그것들을 적용 할 것을 제안한다. 그게 다야. –

+0

@RobertRamey 라이브러리를 작성 중이며 컴파일 타임 상수가 필요한 컨텍스트에서 사용할 수있는 함수가 있다면'constexpr'을 사용하지 않고 사용했을 때만 진단을받을 수 있습니다. 포괄적 인 단위 테스트가 있지만 라이브러리 클라이언트에 대한 문서 문제가있는 경우에는 괜찮습니다. 주어진 함수가'constexpr'을 의도하고 라이브러리의 차후 버전에 그대로 남아 있을지 아니면 현재 구현 된'constexpr'일까요? 어떻게하면 표준 라이브러리의 무엇이든지'constexpr'에 이식 할 수 있습니까? – mattnewport

+0

첫 번째 질문 - 뭔가가 constexpr인지 확실히 알고 싶다면 명시 적으로 테스트해야합니다. 이것은 다소 말하기와 비슷합니다. 만약 당신이 뭔가를 constexpr로 표현하고 싶다면 그렇게 말하십시오. 나는 이것에 동의하지 않는다. –

관련 문제