C ++ 'da, sayı sabitse veya değil ise, static_cast <unsigned> negatif sayı neden farklılık gösterir?


28

Ne araçlarının C ++ kuralları böyle eşit olduğu yanlış ?. Verilen:

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

Örneğin, 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;
}

Aşağıdaki çıktıyı üretir:

 f=ffffffff
cf=0

6
Bir oy verin: tanımlanmamış davranış hakkında unutulmuş bir kural tarafından yakalandınız!
Bathsheba

Negatif bir şamandırayı imzasız hale dönüştürmek için hangi sonuçları beklersiniz?
Amadeus

1
@Amadeus muhtemelen negatif tamsayıyı dönüştürürken elde ettiğimiz normal sargı. UB olup olmadığını kontrol etmek zorunda kaldım çünkü bu beni şaşırttı.
16'da programcı

1
@Amadeus, daha çok farkı anlamak için bir durumdu. Birkaç hafta önce bir yazım hatası düzelttim ... const-float açıkça imzasız (bug) ve dolaylı olarak imzalı (imzalı bir işlev parametresi olarak) geri döküm. Daha sonra orijinal hatanın neden işlevde sıfır değerine neden olduğunu düşündüm. Testler şamandıranın sabit olduğu için olduğunu göstermektedir. Açıkça imzasız ve sonradan imzalı olarak imzalı olarak atılan bir const olmayan şamandıra aynı davranışla sonuçlanmadı - iki kez dökülen const, orijinal ve beklenen değere sahipti .
tarihinde GreyMattR

Yanıtlar:


26

Programınızın davranışı tanımlanmamıştır : C ++ standardı, negatif kayan nokta türünün bir unsignedtüre dönüştürülmesini tanımlamaz .

(Bilinen tamamlama davranışının yalnızca negatif integral türleri için geçerli olduğuna dikkat edin .)

Bu nedenle, program çıktısını açıklamaya çalışmanın pek bir anlamı yoktur.


1
Bunun yerine float-> int-> unsigned'i dönüştürürsem tanımlanır mı?
Yksisarvinen

5
@Yksisarvinen: Sadece floatbir int.
Bathsheba

UB'nin doğru cevap olduğunu kabul ediyorum ve bunun sonu olmalı ... ama verilen ... Derleyici Explorer'daki (clang / gcc / djgpp) tüm derleyicilerin neden ürettiğini açıklayan olası derleyici-yazar yanıtı nedir? eşdeğer (UB) çıkış?
GreyMattR

5
@GreyMattR Derleyici, döküm sırasında değerin negatif olacağını garanti ederse, dökümün sonucunu başlatılmadan bırakabilir veya sıfıra ya da yapmak istediği herhangi bir şeye ayarlayabilir. Derleyici bunu ispatlayamazsa, döküm gerçekleştirmek için kod üretmesi gerekir. Bu gibi amaçlar için, kodu işaretli tamsayı türüne dönüştürmek için yeniden kullanabilir (sonuç yalnızca döküm UB ise "yanlış" olur, bu aslında yanlış olmadığı anlamına gelir). Daha agresif bir optimizasyonla, sabit olmayan durumda döküm yayınlanmayacaktır.
Brian

@Brian, bu yararlı açıklama için teşekkürler.
GreyMattR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.