Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?
-
Hi(gh)!
Mittlerweile bin ich im Kapitel 10 "Fortgeschrittene Zeigertechnik" von Goll/Grüner/Wiese angekommen (ja, ich weiß, das Buch ist nicht wirklich der Hit, aber ich habe im Moment nichts Moderneres zur Hand, höchstens noch den ollen Kernighan/Richie...) - und wundere mich, wieso g++ standardmäßig bei den im Betreff genannten Typwandlungen eine Fehlermeldung schmeißt bzw. man das Flag "fpermissive" setzen muss (und selbst dann noch eine Warnung bekommt)! Macht man sowas heutzutage einfach nicht mehr? Wie würde man in aktuellem C z. B. das hohe und niedrige Byte aus einem short int auslesen?
Bis bald im Khyberspace!
Yadgar
-
Kein Code.
Keine Fehlermeldung.
g++ für C?
-
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Reguläre Zeiger in Nullzeiger wandeln und zurück
Hä? Was soll das sein, wie soll das gehen?
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Wie würde man in aktuellem C z. B. das hohe und niedrige Byte aus einem short int auslesen?
Viele Wege führen nach Rom:
#include <stdio.h> #include <stdint.h> typedef union short_byte_reader_tag { int16_t s; unsigned char b[2]; } short_byte_reader; int main(void) { int16_t value = 0xffaa; // 1 unsigned char *p = (unsigned char*)&value; printf("%02x %02x\n\n", p[1], p[0]); // 2 unsigned char high = (value >> 8); unsigned char low = (value & 0xff); printf("%02x %02x\n\n", high, low); // 3 short_byte_reader sbr; sbr.s = value; printf("%02x %02x\n\n", sbr.b[1], sbr.b[0]); }
Der Cast in (1) ist in C nur zu
char *
undunsigned char *
erlaubt, in C++ zu beiden vorher genannten und zustd::byte *
. Alles andere ist unerlaubtes aliasing.Angeblich ist (3), also type punning mit einer
union
(anderen member lesen als zuletzt geschrieben wurde) seit C99 oder C11 erlaubt (aber auf keinen Fall in C++).
-
Hi(gh)!
@swordfish sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Reguläre Zeiger in Nullzeiger wandeln und zurück
Hä? Was soll das sein, wie soll das gehen?
Na, sowas hier:
/* Datei: zgrarith.c */ /* Goll, Grüner, Wiese: C als erste Programmiersprache, Seite 196 */ /* Programm zur Zerlegung einer short int-Zahl in das niederwertige */ /* und das höherwertige Byte */ #include <stdio.h> int main(void) { int i; int* ptr1; void* dummy; unsigned char* ptr2; i = 0xabcd; printf("i ist: %x\n", i); ptr1 = &i; printf("\nptr1 zeigt auf die Adresse: %p", ptr1); printf("\nDer Inhalt an der Adresse ptr1 ist %x", *ptr1); dummy = ptr1; ptr2 = dummy; printf("\nNiederwertiges Byte von i: %x", *ptr2); printf("\nan der Adresse: %p", ptr2); ptr2++; printf("\nAdresse ptr2 wurde um 1 erhöht."); printf("\nHöherwertiges Byte von i: %x", *ptr2); printf("\nan der Adresse: %p", ptr2); return 0; }
Bei mir funktioniert es, allerdings wie gesagt nur bei -fpermissive...
#include <stdint.h>
Die kenne ich noch nicht, d. h. irgendwo in einer Umzugskiste im Keller liegt ein rororo-Taschenbuch mit einer Einführung in die C-Standardbibliothek, das ich vor einigen Jahren mal durchgearbeitet habe... aber bis auf die Funktionen zur Umwandlung von C-Strings in Zahlenwerte ist mir daraus nichts in Erinnerung geblieben! Das kommt davon, wenn man nicht jeden Tag mehrere Stunden programmiert...
typedef union short_byte_reader_tag {
int16_t s;
unsigned char b[2];
} short_byte_reader;Unions verstehe ich noch, aber was ist int16_t? Und wieso nicht einfach unsigned short?
// 2
unsigned char high = (value >> 8);
unsigned char low = (value & 0xff);
printf("%02x %02x\n\n", high, low);Bitverschiebung und bitweise UND-Verknüpfung... habe ich mir schon gedacht, dass das irgendwie so gehen müsste!
// 3
short_byte_reader sbr;
sbr.s = value;short_byte_reader ist wohl eine struct... definiert in stdint.h - oder in stdio.h?
printf("%02x %02x\n\n", sbr.b[1], sbr.b[0]);
}Der Cast in (1) ist in C nur zu `char *` und `unsigned char *` erlaubt, in C++ zu beiden vorher genannten und zu `std::byte *`. Alles andere ist unerlaubtes aliasing. Angeblich ist (3), also type punning mit einer `union` (anderen member lesen als zuletzt geschrieben wurde) seit C99 oder C11 erlaubt (aber auf keinen Fall in C++).
C99! C11! Kein Wunder, dass ich mit meinen Lehrbüchern von Anno Schnee davon nichts mitbekomme... ich weiß, es gibt erschöpfend ausführliche Online-Manuals im Netz, aber mit den Tutorials ist es AFAIK didaktisch nicht so weit her... und mir Wissen Schnipsel für Schnipsel zusammenzupuzzeln und dabei dann doch regelmäßig falsch abzubiegen ist mir einfach zu frustig!
Ich komme mir so grenzenlos dumm und beschränkt vor...
Bis bald im Khyberspace!
Yadgar
-
Das Problem liegt vermutlich darin, dass du das mit dem g++ übersetzt. Das ist ein C++-Compiler, wie der Name vielleicht schon vermuten lässt.
Außerdem gehts hier nicht um Nullzeiger, sondern um void-Zeiger.
-
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Unions verstehe ich noch, aber was ist int16_t? Und wieso nicht einfach unsigned short?
int16_t
ist ein ganzzahliger Datentyp aus<stdint.h>
, der (im Gegensatz zushort
) garantiert 16 Bits breit ist.@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
short_byte_reader ist wohl eine struct... definiert in stdint.h - oder in stdio.h?
Schau mal genau ... das ist die über
main()
definierteunion
.
-
Hi(gh)!
@bashar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Das Problem liegt vermutlich darin, dass du das mit dem g++ übersetzt. Das ist ein C++-Compiler, wie der Name vielleicht schon vermuten lässt.
Gibt es heutzutage noch dedizierte C-Compiler für Linux?
Außerdem gehts hier nicht um Nullzeiger, sondern um void-Zeiger.
O.k., da habe ich mich unsauber ausgedrückt, ich meinte natürlich void-Zeiger!
Bis bald im Khyberspace!
Yadgar
-
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Gibt es heutzutage noch dedizierte C-Compiler für Linux?
Ja, sicher. Zum Beispiel g++
Lass dich mal nicht verunsichern, g++ kann durchaus Standard C-ohne-++.
Oder auch Clang.C99! C11! (...)
Ich komme mir so grenzenlos dumm und beschränkt vor...Ja, kann ich verstehen. Musst du aber nicht. Ob du das weiterverfolgen willst ist natürlich deine Sache, aber dumm vorkommen musst du dir dabei sicher nicht. Es gibt auch einige "Experten" die immer noch nicht mitbekommen haben dass es in C jetzt auch strict aliasing gibt - und massig Code mit undefiniertem Verhalten schreiben.
-
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Gibt es heutzutage noch dedizierte C-Compiler für Linux?
Weiß nicht genau, was du mit dediziert meinst. Es wäre wohl ein bisschen unpraktisch, wenn ein OS, dessen halbe Softwarelandschaft inklusive Kernel in C geschrieben ist, keinen C-Compiler hätte. Der gcc kann C und C++ (und Ada und Fortran, glaub ich) übersetzen, aber wenn du ihn mit
g++
aufrufst, macht er C++.O.k., da habe ich mich unsauber ausgedrückt, ich meinte natürlich void-Zeiger!
Nee, das ist einfach falsch. Nullzeiger gibt es ja auch.
-
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Ich komme mir so grenzenlos dumm und beschränkt vor...
Hör endlich auf mit der Zurschaustellung Deines Selbstmitleids. Echt zum Kotzen!
-
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Hi(gh)!
...Bis bald im Khyberspace!
Ich komme mir so grenzenlos dumm und beschränkt vor...Ja, mir auch.
-
@belli Belli, sei lieb!!
-
@hustbaer sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Gibt es heutzutage noch dedizierte C-Compiler für Linux?
Ja, sicher. Zum Beispiel g++
Lass dich mal nicht verunsichern, g++ kann durchaus Standard C-ohne-++.
Oder auch Clang.Naja, mit g++ x.c -c kommt halt der Fehler:
x.c: In function ‘int main()’:
x.c:25:10: error: invalid conversion from ‘void*’ to ‘unsigned char*’ [-fpermissive]
ptr2 = dummy;
^~~~~Mit gcc nicht.
-
@manni66 sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@hustbaer sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Gibt es heutzutage noch dedizierte C-Compiler für Linux?
Ja, sicher. Zum Beispiel g++
Lass dich mal nicht verunsichern, g++ kann durchaus Standard C-ohne-++.
Oder auch Clang.Naja, mit g++ x.c -c kommt halt der Fehler:
x.c: In function ‘int main()’:
x.c:25:10: error: invalid conversion from ‘void*’ to ‘unsigned char*’ [-fpermissive]
ptr2 = dummy;
^~~~~Mit gcc nicht.
Du sollst dem g++ ja auch sagen, dass er für C compilieren soll. Was durchaus möglich ist, aber halt unnötig umständlich.
-
@seppj sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@manni66 sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@hustbaer sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
@yadgar sagte in Reguläre Zeiger in Nullzeiger wandeln und zurück - nicht mehr Standard?:
Gibt es heutzutage noch dedizierte C-Compiler für Linux?
Ja, sicher. Zum Beispiel g++
Lass dich mal nicht verunsichern, g++ kann durchaus Standard C-ohne-++.
Oder auch Clang.Naja, mit g++ x.c -c kommt halt der Fehler:
x.c: In function ‘int main()’:
x.c:25:10: error: invalid conversion from ‘void*’ to ‘unsigned char*’ [-fpermissive]
ptr2 = dummy;
^~~~~Mit gcc nicht.
Du sollst dem g++ ja auch sagen, dass er für C compilieren soll. Was durchaus möglich ist, aber halt unnötig umständlich.
Mir ist das klar. Dem Fragesteller aber sicher nicht.