2016-04-16 20 views
1

Ich bin ziemlich neu in C/C++, und ich versuche, einige Richtlinien zu folgen, die die Verwendung der definierten stdint.h definiert, wo möglich (uint8_t, etc anstelle von unsigned char).Warum verwenden Windows-API-Aufrufe, die mit Bytes arbeiten (z. B. 'recv'), char *, das standardmäßig signiert ist?

Es scheint jedoch, wenn Sie eine API aufrufen, die einen char* Puffer (wie recv) erwartet, müssen Sie den Typ verwenden, der API diktiert.

Was ich nicht verstehe ist, warum, wenn Sie Bytes lesen, würden Sie es nicht ohne Vorzeichen sein wollen, so erhalten Sie Werte zwischen 0 und 255 anstelle von -128 und 127

I Ich weiß nicht, ob das für die Implementierung spezifisch ist, aber ich habe nur char default zu signed gesehen.

Wird erwartet, dass Sie die Ergebnisse von Aufrufen wie diesem in eine unsigned char* oder uint8_t* umwandeln, damit Sie die höheren positiven Werte interpretieren können?

+0

Da die Aufrufe nur einen Zeiger benötigen, nehme ich nicht an, dass die ursprünglichen Designer dachten, dass es so oder so von Bedeutung ist. –

+2

Zuerst zu lernen ist, gibt es keine Sprache C/C++, aber nur die zwei ** verschiedenen ** Sprachen C und C++. Sagte, dass der C-Standard keine bestimmte Signed-Ness für 'char' definiert. Also das ist eine Windows-Angelegenheit. Und die WinAPI ist weit davon entfernt, den modernen C-Programmierstil zu verwenden; 'stdint.h' war nicht verfügbar, wenn es entworfen wurde. Und es spielt wahrscheinlich keine Rolle, ob 'char' für diese Funktionen signiert oder unsigniert ist. – Olaf

+0

@Olaf Ah, ok. Es ist also implementierungsspezifisch? Und ich muss es nur interpretieren, macht aber Sinn für das, was ich schreibe? – Twicetimes

Antwort

2

Unter Windows ist recv Teil der Winsock-API, die als Klon der 4.2BSD-Sockets-API entstand. 4.2BSD ist älter als ANSI C und das void Schlüsselwort, so dass es char * verwendet, weil es zu einem Zeitpunkt einem generischen Zeiger am nächsten kam.

Später, nachdem void erfunden wurde, BSD und andere Unix-Systeme aktualisiert die Definition von recv, und jetzt verwenden sie alle void *. Die Motivation für diese Änderung ist klar: char * ist nicht wirklich ein generischer Zeiger, verwenden Sie es als eine macht Ihren Code hässlicher, mit mehr Casts. Die void * Version von recv auch von POSIX beauftragt, so der einzige Betriebssystem-Anbieter, der es nicht hat, ist derjenige, der am wenigsten über POSIX-Compliance und Code-Ästhetik kümmert ... Microsoft.

+0

Also wurde von den POSIX-konformen Versionen immer erwartet, dass Sie es trotzdem konvertieren müssen? – Twicetimes

+0

Nein, mit einem 'void *' brauchst du nie einen Cast. Sie können jeden beliebigen Zeiger übergeben. –

+0

Ok, aber wenn ich die Ergebnisse interpretiere, muss ich vermutlich nach uint8_t oder ähnlichem umwandeln, sonst würde ich zum Beispiel, wenn ich versuche, die Bytewerte zu lesen, -128 anstelle von 128 bekommen? – Twicetimes