C ++에서 "함수 독"이란 무엇을 의미합니까?


96

CppCon에서 Scott Schurr의 "Introducing constexpr" 강연의 끝 에서 그는 "기능을 독살하는 방법이 있습니까?"라고 묻습니다. 그런 다음 (비표준 방식이긴하지만) 다음과 같이이를 수행 할 수 있다고 설명합니다.

  1. 퍼팅 throwA의 constexpr기능
  2. 미해결 선언 extern const char*
  3. 해결되지 않은 참조 extern의를throw

나는 내가 여기서 내 깊이에서 약간 벗어난 것 같지만 궁금합니다.

  • "기능 중독"이란 무엇을 의미합니까?
  • 그가 설명하는 기술의 중요성 / 유용성은 무엇입니까?

1
그 용어에 대해 들어 본 적이 없습니다. 간결한 예를 들어 설명해주세요!
πάντα ῥεῖ 2015

6
@ πάνταῥεῖ, 방금 명확히했습니다. 이 용어는 '작은 원으로 널리 알려져 있습니다'
SergeyA

4
그는 constexpr함수 에 대한 모든 호출이 컴파일 타임에 평가 되도록하는 것에 대해 이야기하고 있습니다.
TC

@TC Right-- 그는 constexpr함수가 컴파일 타임이나 런타임에 사용될 수 있다고 언급했습니다 . 그래서 이것은 런타임에 사용할 수 없도록 강제하는 방법입니까? 언제 유용합니까?
sudo make install

3
특히 C ++ 11에서 constexpr함수는 제약으로 인해 가장 효율적인 구현이 아닌 경우가 많으므로 런타임에 평가하는 것을 원하지 않을 수 있습니다. 또는 (그의 예에서와 같이) 오류 사례 일 수 있습니다.
TC

답변:


106

일반적으로 기능을 사용할 수 없게 만드는 것을 의미합니다. 예를 들어 프로그램에서 동적 할당 사용을 금지하려는 경우 해당 기능을 사용할 수 없도록 "중독" malloc할 수 있습니다.

비디오에서 그는 그것을 좀 더 구체적인 방식으로 사용하고 있습니다. "컴파일 타임만을 강제하는 방법?"이라고 말하는 함수 중독에 대해 이야기 할 때 표시되는 슬라이드를 읽으면 분명합니다.

그래서 그는 런타임에 호출 할 수 없도록 함수를 "중독"하는 것에 대해 이야기하고 있습니다. 따라서 상수 표현식 에서만 호출 수 있습니다. 이 기술은 컴파일 타임 컨텍스트에서 호출 될 때 절대로 취해지지 않는 함수에 분기를 포함하고 해당 분기에 오류를 발생시키는 무언가를 포함하도록 만드는 것입니다.

throw이 함수의 컴파일시 호출시에 도달하지 못했다대로 (당신이 컴파일시에 예외를 던질 수 없기 때문에 메모리 할당과 같은 본질적으로 역동적 인 동작의) 표현은 한하는 constexpr 기능에 허용됩니다. 따라서 정의되지 않은 기호를 참조하는 throw 표현식은 컴파일에 실패하기 때문에 컴파일 타임 호출 중에 사용되지 않으며 정의되지 않은 기호로 인해 링커 오류가 발생하기 때문에 런타임에 사용할 수 없습니다.

정의되지 않은 심볼은 함수의 컴파일 타임 호출에서 "odr-used"가 아니기 때문에 실제로 컴파일러는 심볼에 대한 참조를 생성하지 않으므로 정의되지 않은 것이 좋습니다.

유용합니까? 그는 그것을 수행 하는 방법 을 시연 하고 있으며 반드시 그것이 좋은 아이디어이거나 널리 유용하다고 말하는 것은 아닙니다. 어떤 이유로 든 할 필요가 있다면 그의 기술이 문제를 해결할 수 있습니다. 그럴 필요가 없다면 걱정할 필요가 없습니다.

유용 할 있는 한 가지 이유 는 일부 작업의 컴파일 타임 버전이 효율적이지 않을 때입니다. constexpr 함수에서 허용되는 식의 종류에는 제한이 있습니다 (특히 C ++ 11에서는 일부 제한이 C ++ 14에서 제거됨). 따라서 계산을 수행하기위한 두 가지 버전의 함수가있을 수 있습니다. 하나는 최적이지만 constexpr 함수에서 허용되지 않는 표현식을 사용하는 것이고 다른 하나는 유효한 constexpr 함수이지만 실행시 호출되면 성능이 저하됩니다. 시각. 차선책을 감염시켜 런타임 호출에 사용되지 않도록하여 런타임 호출에보다 효율적인 (비 constexpr) 버전이 사용되도록 할 수 있습니다.

NB 컴파일 타임에 사용되는 constexpr 함수의 성능은 어쨌든 런타임 오버 헤드가 없기 때문에 그다지 중요하지 않습니다. 컴파일러가 추가 작업을 수행하도록하여 컴파일 속도를 늦출 수 있지만 런타임 성능 비용은 발생하지 않습니다.


1
나는 슬라이드의 텍스트를 읽었지만 그가 사용하는 용어와의 연관성을 보지 못했습니다. 당신이 그것을 설명 했으니 이제는 분명하지만 그 당시에는 그것을 보지 못했습니다. 이 훌륭한 답변에 감사드립니다. 저는이 웹 사이트를 좋아합니다.
sudo make install

@PravasiMeet, 자신의 질문을하고, 다른 것에 대한 다른 사람의 질문에 대한 의견을 가로 채지 마십시오. 간단한 해결책은 모든 번역 단위에서 삭제 된 것으로 정의하거나 정의되지 않은 기호를 참조하는 고유 한 정의로 바꾸는 것입니다.
조나단 Wakely

17

식별자를 '중독'한다는 것은 '중독'이후 식별자에 대한 모든 참조가 하드 컴파일러 오류임을 의미합니다. 예를 들어,이 기술은 하드 폐기 (함수 IS 폐기 됨, 절대 사용하지 않음)에 사용할 수 있습니다.

GCC에는 전통적으로이를위한 pragma가있었습니다 #pragma GCC poison.


1
예,하지만 그 강연에서 사용 된 의미에서는 그렇지 않습니다.
TC

@TC, 좋아, 나는 아마 :) 응답하기 전에주의해야
SergeyA
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.