GCC: konvertieren von uint64_t in Byte Array

Gast #7211658
Lesenswert?

Peter schrieb:
> Hallo,
>
> das Bit-Shiften funktioniert nicht. Die oberen 32 Bit sind immer 0.
>
> uint64_t ullValue = 0xFFFFFFFF;
> uint8_t ucValue = (uint8_t)((uint64_t)(ullValue >> 40));
>
> Ergebnis: ucValue = 0
>
> Wie kann ich auf die oberen 32 Bit zugreifen ?
>
> Gruß Peter

Ist ja auch richtig, wenn man den uint64_t nur zur Hälfte befüllt.
Versuchs mal mit 0xFFFFFFFFFFFFFFFF...

Ach, was solls:
1
uint64_t ullValue = 0xFFFFFFFFFFFFFFFF;
2
uint8_t byteArray[8];
3
    
4
for (int i = 0; i < 8; i++)
5
{
6
    byteArray[i] = (uint8_t)(ullValue >> (8 * i));
7
    printf("%d. 0x%x\n", i + 1, byteArray[i]);
8
}
Gast #7212010
Lesenswert?

Walter T. schrieb:
> Ich weiß
> gerade nur nicht, warum. Zumindest bei der Erzeugnung eines
> 32-Bit-Binaries auf einem 64-Bit-System.

Weil der Compiler "annimmt", dass es sich bei "0" um eine Zahl aus dem 
Zielzahlenbereich "uint64_t" handelt?!

Peter D. schrieb:
> Man kann auch einfacher schreiben:uint64_t ullValue = -1;
> Als Zuweisung sind signed Werte erlaubt. Sie werden dann in den
> entsprechenden Binärwert konvertiert.

Da würde ich vermuten, dass ein Warning erzeugt wird (zumindest meckert 
"mein" Keil rum: "warning:  #68-D: integer conversion resulted in a 
change of sign"). Ein Cast sollte reichen.
#7212013
Lesenswert?

Ich habe meinen vorheriges Edit gelöscht, weil mein vorheriger Einwand 
gegenstandslos geworden war. Deswegen passt das Zitat nicht mehr zu 
meinem Beitrag.

Sinngemäß stand da: "Nanu, uint64_t a = ~0; funktiert ja."

STK500-Besitzer schrieb:
> Weil der Compiler "annimmt", dass es sich bei "0" um eine Zahl aus dem
> Zielzahlenbereich "uint64_t" handelt?!

Nein, es liegt daran, dass mein Build-Prozeß eine 64-Bit-EXE erzeugt 
hat. Ich hatte es nur vergessen, dass ich vor längerer Zeit umgestellt 
habe.
Persönliche Seite #7212020
Lesenswert?

Walter T. schrieb:
> Wenn schon, dann ~0ULL.

Aber ist uint64_t denn immer unsigned long long?

Da doch lieber
1
UINT64_MAX
 (in C) oder
1
std::numeric_limits<std::uint64_t>::max()
 (C++).

Es ginge auch noch
1
((uint64_t) ~((uint64_t) 0))
 in C bzw.
1
static_cast<std::uint64_t> (~std::uint64_t { 0 })
 in C++, aber schön ist anders. Der äußere Cast ist eventuell je nach 
Plattform nötig um Integer Promotion zu umgehen.
#7212021
Lesenswert?

Walter T. schrieb:
in, es liegt daran, dass mein Build-Prozeß eine 64-Bit-EXE erzeugt
> hat. Ich hatte es nur vergessen, dass ich vor längerer Zeit umgestellt
> habe.

Nein.
Das Literal 0 hat den Typ int, ~0 invertiert die Bits des int, das 
Ergebnis ist wieder der Typ int (Promotionsregeln) und hat den Wert -1. 
Mit -1 wird dann der uint64_t initialisiert, und dabei wird auf uint64_t 
konvertiert.
#7212130
Lesenswert?

Udo K. schrieb:
> Wilhelm M. schrieb:
>> Seit C23 ist 2'er-Komplement verpflichtend.
>
> Das nützt dir nur heute nichts.

Doch (bei gcc): -std=c2x

Zitat cppreference:

Prior to C23, the C Standard allowed any signed integer representation, 
and the minimum guaranteed range of N-bit signed integers was from
 (e.g. -127 to 127 for a signed 8-bit type), which corresponds to the 
limits of one's complement or sign-and-magnitude.

However, all popular data models (including all of ILP32, LP32, LP64, 
LLP64) and almost all C compilers use two's complement representation 
(the only known exceptions are some compliers for UNISYS), and as of 
C23, it is the only representation allowed by the standard, with the 
guaranteed range from
 (e.g. -128 to 127 for a signed 8-bit type).

Mit einem UB, was in der Tat heute(!) nicht auftritt, kann ich gut 
leben.
Gast #7212165
Lesenswert?

Wilhelm M. schrieb:
>> Das nützt dir nur heute nichts.
>
> Doch (bei gcc): -std=c2x

Die gcc Homepage meint dazu:
  A further version of the C standard, known as C2X, is under 
development;
  experimental and incomplete support for this is enabled with -std=c2x.

Aber ich kenne keine aktuelle CPU, die nicht 2-er Kompliment hat, von 
daher ist die Diskussion sinnlos...
#7212243
Lesenswert?

Veit D. schrieb:
> Hallo,
>
> Schade das es nicht konsequent umgesetzt wird. Das würde viele Probleme
> beheben. Darf ich fragen was ein Trap ist?
>> ... representation (typically 2's complement), it may trap on some
>> platforms or due to compiler options (e.g. -ftrapv in GCC and Clang) ...

Ein trap ist ein Software-Interrupt, was das genau bedeutet, ist dann 
eben sehr plattformspezifisch. Auf x86/*nix wird dem Prozess ein SIGABRT 
gesendet.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren