Wie schreibe ich ein kurzes Literal in C ++?


120

Sehr grundlegende Frage: Wie schreibe ich ein shortLiteral in C ++?

Ich kenne folgendes:

  • 2 ist ein int
  • 2U ist ein unsigned int
  • 2L ist ein long
  • 2LL ist ein long long
  • 2.0f ist ein float
  • 2.0 ist ein double
  • '\2'ist ein char.

Aber wie würde ich ein shortLiteral schreiben ? Ich habe es versucht, 2Saber das gibt eine Compiler-Warnung.


10
Ich denke, kurzes Literal wird nicht nur aufgrund der Tatsache unterstützt, dass weniger als int während der Evaluierung zu int "befördert" wird. int hat die natürlichste Größe. Dies wird in C ++ als Ganzzahl-Heraufstufung bezeichnet.
user534498

Antworten:


82
((short)2)

Ja, es ist nicht nur ein kurzes Wort, sondern eher ein Casted-Int, aber das Verhalten ist das gleiche und ich denke, es gibt keinen direkten Weg, dies zu tun.

Das habe ich getan, weil ich nichts darüber finden konnte. Ich würde vermuten, dass der Compiler klug genug wäre, dies so zu kompilieren, als wäre es ein kurzes Literal (dh er würde nicht wirklich ein int zuweisen und es dann jedes Mal umwandeln).

Das Folgende zeigt, wie sehr Sie sich darüber Sorgen machen sollten:

a = 2L;
b = 2.0;
c = (short)2;
d = '\2';

Kompilieren -> zerlegen ->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d

Das habe ich getan, weil ich nichts darüber finden konnte. Ich würde vermuten, dass der Compiler klug genug wäre, dies so zu kompilieren, als wäre es ein kurzes Literal (dh er würde nicht wirklich ein int zuweisen und es dann jedes Mal umwandeln).
Kip

Die "Besetzung" macht eigentlich nichts. Es gibt keine Assembler-Anweisung "cast", wenn es sich um C oder C ++ handelt (.NET MSIL ist jedoch eine andere Geschichte). Dort auf dem Metall ist alles nur binäre Ziffern
Isak Savo

9
Welche Arten von a, b, c und d gibt es oben?
Ates Goral

2
@Ates Goral: Alle Ints. Ein Wechsel zu short oder char würde vermutlich die Anweisung in movw oder movb auf der ganzen Linie ändern.

2
Das ist kein kurzes Wort. Wenn Sie diese Umwandlung verwenden und mit GCC und der Option -Wconversion kompilieren, erhalten Sie weiterhin eine Compilerdiagnose für die Anweisung short foo = 1; foo += (short)2;. Dies kann jedoch aufgrund der Ganzzahl-Promotion nicht umgangen werden.
Harper

51

Mit C ++ 11 kommen Sie dem, was Sie wollen, ziemlich nahe. (Suchen Sie nach "benutzerdefinierten Literalen", um mehr zu erfahren.)

#include <cstdint>

inline std::uint16_t operator "" _u(unsigned long long value)
{
    return static_cast<std::uint16_t>(value);
}

void func(std::uint32_t value); // 1
void func(std::uint16_t value); // 2

func(0x1234U); // calls 1
func(0x1234_u); // calls 2

// also
inline std::int16_t operator "" _s(unsigned long long value)
{
    return static_cast<std::int16_t>(value);
}

6
shortphysisch kann std::uintnichts sein, da es ein signierter Typ ist. Und es ist nicht als entweder 16 Bit oder die gleiche Art wie ein erforderlich std::int16_t... , die sich nicht einmal erforderlich ist, existieren in einer gegebenen Implementierung , wenn die Plattform nicht die genaue Breitentyp liefern kann. Die Kernidee dieser Antwort ist gut, aber sie wird durch die unerklärliche Tangente an nicht verwandte Typen abgewertet, nach denen das OP nicht gefragt hat.
underscore_d

Hinweis Benutzerdefinierte Literale werden in Visual Studio erst in VS2015 unterstützt: msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
Petersilie72

Ich weiß nicht, ob ich es lieben oder hassen soll, aber dies ist das letzte Stück meines eigentlich starken Integer-Systems in C ++, an dem ich arbeite. Es ist erstaunlich.
Sahsahae

Echo @underscore_d, würde ich aber nach einer Bearbeitung auf shortwie von OP aked upvote.
v.oddou

28

Sogar die Autoren des C99-Standards waren davon betroffen. Dies ist ein Ausschnitt aus der gemeinfreien stdint.hImplementierung von Danny Smith :

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
    "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
    9899:1999 as initially published, the expansion was required
    to be an integer constant of precisely matching type, which
    is impossible to accomplish for the shorter types on most
    platforms, because C99 provides no standard way to designate
    an integer constant with width less than that of type int.
    TC1 changed this to require just an integer constant
    *expression* with *promoted* type."
*/

18

Wenn Sie Microsoft Visual C ++ verwenden, sind für jeden Ganzzahltyp Literalsuffixe verfügbar:

auto var1 = 10i8;  // char
auto var2 = 10ui8; // unsigned char

auto var3 = 10i16;  // short
auto var4 = 10ui16; // unsigned short

auto var5 = 10i32;  // int
auto var6 = 10ui32; // unsigned int

auto var7 = 10i64;  // long long
auto var8 = 10ui64; // unsigned long long

Beachten Sie, dass dies eine nicht standardmäßige Erweiterung ist und nicht portabel ist . Tatsächlich konnte ich auf MSDN nicht einmal Informationen zu diesen Suffixen finden.


1
Wenn Sie eines der Suffixe verfolgen, werden Sie sehen, dass zB ""ui8definiert ist als '\000', was im Wesentlichen ist '\0'.
Nikita

10

Sie können auch die Pseudokonstruktorsyntax verwenden.

short(2)

Ich finde es lesbarer als Casting.


4
Es wird als "funktionaler Besetzungsausdruck" bezeichnet. Ich mag es auch sehr, besonders wenn ich mit der Windows-API programmiere.
Klaus Triendl

6

Soweit ich weiß, gibt es kein solches Suffix. Die meisten Compiler warnen jedoch, wenn ein ganzzahliges Literal zu groß ist, um in die Variable zu passen, in der Sie es speichern möchten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.