C ++에서 숫자가 상수인지 아닌지에 대해 음수의 static_cast <unsigned>가 다른 이유


28

equalfalse 를 의미하는 C ++ 규칙은 무엇입니까 ? 주어진:

float f {-1.0};
bool equal = (static_cast<unsigned>(f) == static_cast<unsigned>(-1.0));

예 : https://godbolt.org/z/fcmx2P

#include <iostream>

int main() 
{
          float   f {-1.0};
    const float  cf {-1.0};

    std::cout << std::hex;
    std::cout << " f" << "=" << static_cast<unsigned>(f) << '\n';
    std::cout << "cf" << "=" << static_cast<unsigned>(cf) << '\n';

    return 0;
}

다음과 같은 출력을 생성합니다.

 f=ffffffff
cf=0

6
공감하기 : 당신은 정의되지 않은 행동에 대해 잊혀진 규칙에 사로 잡혔습니다!
Bathsheba

음수 부동 소수점을 부호없는 것으로 변환하는 결과는 무엇입니까?
아마데우스

1
@Amadeus는 아마도 음의 정수를 변환 할 때 얻을 수있는 일반적인 랩입니다. 그것이 나를 놀라게했기 때문에 그것이 UB인지 확인해야했습니다.
AProgrammer

1
@Amadeus는 차이를 이해하는 경우가 더 많았습니다. 몇 주 전에 오타 버그를 수정했습니다 ... const-float는 명시 적으로 부호없는 (버그)로 캐스팅되고 암시 적으로 부호있는 함수 매개 변수로 다시 서명됩니다. 나중에 원래 버그가 왜 함수에서 0 값을 유발하는지에 대해 숙고했습니다. 테스트에 따르면 float가 const이기 때문입니다. 서명되지 않은 명시 적으로 캐스팅 한 후 암시 적으로 같은 bahaviour 발생하지 않았다 다시 서명에 캐스팅 const가 아닌 플로트 - 두번 캐스트 const가 아닌이 있었다 원래 예상 값입니다.
GreyMattR

답변:


26

프로그램의 동작은 정의되어 있지 않습니다 . C ++ 표준에서는 음의 부동 소수점 유형유형 으로 변환하지 않습니다 unsigned.

익숙한 랩 어라운드 동작은 음의 정수 유형 에만 적용됩니다 .

따라서 프로그램 출력을 설명하려는 시도는 거의 없습니다.


1
float-> int-> unsigned를 대신 변환하면 정의됩니까?
Yksisarvinen

5
@Yksisarvinen : float의 범위 내에있는 경우에만 int.
Bathsheba

나는 UB가 정답이라는 것을 인정하고 그 끝이되어야합니다 ...하지만 주어진 ... 컴파일러 컴파일러 (clang / gcc / djgpp)의 모든 컴파일러가 생성하는 이유를 설명하는 컴파일러 작성자의 대답은 무엇입니까? 동등한 (UB) 출력?
GreyMattR

5
@GreyMattR 컴파일러가 캐스트 시점에서 값이 음수임을 보증 할 수있는 경우 캐스트 결과를 초기화되지 않은 상태로 두거나 0으로 설정하거나 원하는 다른 작업을 수행 할 수 있습니다. 컴파일러가이를 증명할 수 없으면 캐스트를 수행하기위한 코드를 생성해야합니다. 이러한 목적으로 코드를 재사용하여 부호있는 정수 유형으로 캐스트 할 수 있습니다 (캐스트가 UB 인 경우에만 결과가 "잘못된"이므로 실제로 잘못되지 않습니다). 보다 적극적인 최적화를 사용하면 비 정확한 경우에도 캐스트가 방출되지 않습니다.
브라이언

@Brian, 그 유용한 설명에 감사드립니다.
GreyMattR
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.