>

메타 프로그래밍 트릭을 사용하여 어셈블리 블록에서 SFINAE를 허용 할 수 있습니까? 예를 들어 프로세서에서 "CPUID"와 같은 명령어를 사용할 수 있는지 감지하려면 : (유효한 코드는 아니지만 달성하고자하는 것을 보여줍니다)

// This should work if `CPUID` is a valid instruction on the target architecture
template <
  class... T,
  class = decltype(sizeof...(T), asm volatile("CPUID":::)
>
bool f(T...) {
    return true;
}
// This should fail because `BLAH` is not an instruction
template <
  class... T,
  class = decltype(sizeof...(T), asm volatile("BLAH":::)
>
bool f(T...) {
    return true;
}

  • 답변 # 1

    아래에 열거 된 여러 가지 이유로 인해 질문에 공식화 된 방식을 달성하는 것은 불가능합니다. 그러나 아이디어를 일반화하면 향후 언어 개정에 포함시키는 것이 합리적 일 수 있습니다.

    작동하지 않는 이유 :

    <올>

    asm   블록은 C ++ 컴파일러에 대해 불투명합니다. 이러한 블록의 구문은 컴파일러마다 다릅니다. MS VC ++는 GCC 및 Intel 컴파일러에서 지원하는 방식으로 클로버 목록을 허용한다고 생각하지 않습니다. 또한 Microsoft의 x86_64 컴파일러는 사람들이 내장 함수를 사용하도록 강요함에 따라 어셈블리 블록 지원을 중단했습니다. 그런데 내장 함수의 존재에 의존하여 컴파일 타임 CPU 디스패치를 ​​제공 할 수 있습니까? 이 아이디어를 살펴볼 가치가 있습니다.

    asm  블록은 대상 아키텍처에 따라 다릅니다. 컴파일 타임에 대상 아키텍처를 감지하는 다른 방법이 있습니다.

    현재 존재하거나 부재하는 명령의 개념은 매우 모호하다. 주어진 asm 에 대한 결정을 내릴 권한이있는 기관  expression : 텍스트를 기계 코드로 변환하는 어셈블러 프로그램 또는 실제 코드를 실행하는 대상 프로세서 자체? 두 가지 선택 모두 문제가 있습니다.

    예를 들어, "MOV"는 다양한 아키텍처에서 널리 사용되는 니모닉 이름입니다. 그러나 모든 경우에동일한 지시 사항입니까? 니모닉에 바인딩 된 시맨틱은 관련이없는 아키텍처간에 일치하지 않을 것입니다.

    조립에 성공했다고해서 제대로 실행되는 것은 아닙니다. 예를 들어, Intel 64 아키텍처에서는 명령이 올바르더라도 명령이 #UD (정의되지 않은 명령 신호)로 오류가 발생할 수 있습니다. 동작은 운영 체제에 의해 제어되는 CR0 및 CR4 레지스터의 런타임 값에 따라 달라지기 때문입니다. 어셈블러 프로그램은 어떤 경우에도 잘 처리합니다. 코드를 실행해야합니다. 그러나 교차 컴파일을 수행하고 대상 프로세서가 호스트 프로세서와 일치하지 않아 실행할 수없는 경우 어떻게됩니까?

    오파크 블록의 결과를 먼저 실행하지 않고 결과를 알 수있는 방법은 없습니다. 따라서 컴파일러는 임의의 프로그램을 호출하여 값을 반환하여 템플릿 확장에 사용될 수 있습니다. 그런 다음 이러한 프로그램은 프로세서 또는 명령 감지를 수행하고 찾은 결과를 반환하여 컴파일을 추가로 안내 할 수 있습니다.

    이러한 외부 프로그램의 본질에 대한 가정을 지시하지 않기 때문에 이제는 언어 기능이 될 정도로 추상적으로 보입니다. 이식성 (+ 크로스 컴파일) 문제와 보안 (외부 프로그램 실행 위험) 문제가 여전히 있습니다. 대체로 환경에서 컴파일러로 들어오는 기존 매크로 정의에 의존하는 것이 더 나아 보입니다.

  • 이전 mqtt - python을 사용하여 paho에서 초당 메시지를 늘리는 방법
  • 다음 c++ - 복잡한 반환 유형에 대해 명명 된 반환 값 최적화에 의존 할 수 있습니까?