Was ist die beste Strategie, um "Warnung C4267 möglicher Datenverlust" loszuwerden?

Ich habe älteren Code von Win32 nach Win64 portiert. Nicht, weil die Win32-Objektgröße für unsere Anforderungen zu klein war, sondern nur, weil Win64 jetzt standardmäßiger ist und wir alle unsere Umgebungen auf dieses Format portieren möchten (und wir verwenden auch einige Drittanbieter-Bibliotheken, die eine bessere Leistung bei 64 Bit als bei 32 Bit bieten). .

Wir landen mit Tonnen von;

Warnung C4267: 'Argument': Konvertierung von 'size_t' nach '...', möglicher Datenverlust

Hauptsächlich aufgrund von Code wie:unsigned int size = v.size(); wov ist ein AWL-Container.

Ich weiß, warum die Warnung sinnvoll ist, warum sie ausgegeben wird und wie sie behoben werden kann. In diesem speziellen Beispiel haben wir jedoch nie Fälle erlebt, in denen die Containergröße @ überschritten haunsigned int 's maximaler Wert in der Vergangenheit .... es gibt also keinen Grund, warum dieses Problem auftritt, wenn Code in eine 64-Bit-Umgebung portiert wird.

Wir hatten Diskussionen darüber, was die beste Strategie wäre, um diese lauten Warnungen zu unterdrücken (sie verbergen möglicherweise eine relevante, die wir verpassen werden), aber wir konnten keine Entscheidung über die geeignete Strategie treffen.

So stelle ich hier die Frage, was wäre die am besten empfohlene Strategie?

1. Benutze einenstatic_cast

Benutze einenstatic_cast. Tununsigned int size = static_cast<unsigned int>(v.size());. Ich mag das nicht, weil wir die 64-Bit-Fähigkeit verlieren, eine große Datenmenge in einem Container zu speichern. Da unser Code jedoch nie die 32-Bit-Grenze erreicht hat, scheint dies eine sichere Lösung zu sein ...

2. @ Ersetzunsigned int durchsize_t

Das ist definitiv schwieriger alsunsigned int sizeas @ -Objekt im obigen Beispiel könnte in andere Funktionen übergehen, als Klassenattribut gespeichert werden und das Entfernen einer einzeiligen Warnung könnte dazu führen, dass Hunderte von Codeänderungen vorgenommen werden ...

3. Deaktiviere die Warnung

Das ist höchstwahrscheinlich eine sehr schlechte Idee, da es in diesem Fall auch die Warnung deaktivieren würdeuint8_t size = v.size() was definitiv zu Datenverlust führen kann ....

4. Definiere eine "safe cast" * Funktion und benutze sie

Etwasmöge:

template <typename From, typename To> To safe_cast( const From& value )
{
    //assert( value < std::numeric_limits<To>::max() && value > std::numeric_limits<To>::min() );
    // Edit 19/05: test above fails in some unsigned to signed cast (int64_t to uint32_t), test below is better:
    assert(value == static_cast<From>(static_cast<To>(value))); // verify we don't loose information!
    // or throw....
    return static_cast<To>( value ); 
}

5. Andere Lösungen sind willkommen ...

"Verwenden Sie Lösung 1 in diesem Fall, aber 2 in diesem Fall" könnte eine gute Antwort sein.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage