Hallo, nachfolgender Code dürfte ja zukünftig z.B. auf 128Bit Maschinen gegen die Wand laufen: int main() { char string[] = { "beliebiger Text" }; int ptr; *((unsigned long *) ptr) = malloc(strlen(string) + 1); snprintf((char *) *((unsigned long* ) ptr), strlen(string) + 1, "%s", string); printf("%s\n", (char *) *((unsigned long*) ptr)); } wäre dann long long statt long für die Zukunft sicherer?
Walter K. schrieb: > wäre dann long long statt long für die Zukunft sicherer? Warum machst Du sowas? Der Code ist doch kompletter Unsinn?!? Den kann man komplett ohne irgendwelche "long"-Casts portabel formulieren, ohne die Bitbreite des Prozessors zu kennen.
Walter K. schrieb: > nachfolgender Code dürfte ja zukünftig z.B. auf 128Bit Maschinen gegen > die Wand laufen: Schreibe einfach:
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | |
5 | int main () |
6 | {
|
7 | char string[] = "beliebiger Text"; |
8 | char * ptr; |
9 | |
10 | ptr = malloc(strlen(string) + 1); |
11 | snprintf(ptr, strlen(string) + 1, "%s", string); |
12 | printf("%s\n", ptr); |
13 | |
14 | return 0; |
15 | }
|
Funktioniert mit Bitbreiten von 8, 16, 32, 64 und 128. Wenn die ersten Maschinen mit 256 Bit rauskommen, kannst Du Dich nochmal melden. P.S. Das obige kann man auch noch um einiges performanter machen. Aber das ist jetzt hier nicht die Aufgabe gewesen ;-)
Frank M. schrieb: > Warum machst Du sowas? Der Code ist doch kompletter Unsinn?!? selbstverständlich ist der Code Unsinn! Das haben Beispiele oft so an sich! Es geht doch darum, zu hinterfragen was passiert eigentlich: wenn solch Code mal auf einer Maschine mit 128Bit Adressraumbreite läuft und Adressen mittels long auf 64Bit gecastet sind! Mit der Prozessorbitbreite hat das erst mal gar nichts zu tun!
long long und even longer erinnern mich an zwei Figuren aus einem Film. Beim Programmieren interessiert den einen oder auch den anderen, welcher Wertebereich vorkommen darf bzw. soll. Natürlich kannst Du jederzeit auch mit 256 Bit langen Zahlen (und länger) arbeiten, so die dazu nötigen Bibliotheken verfügbar sind und Du sie auch eingebunden hast. Rund um die Mikrocontrollerei stellt sich hierbei aber immer wieder die Frage: Ist das nötig? Mehr Speicher für die Variablen; größere Rechenzeiten; ständige Internkonvertierung;-)
Walter K. schrieb: > wäre dann long long statt long für die Zukunft sicherer? Nein. Sicherer wäre, so einen Mist zu unterlassen und korrekte Datentypen zu nutzen. Seit C99 gibt es nämlich uintptr_t, was ein Integer ist, der einen Pointer fassen kann - und der ist automatisch und plattform-unabhängig so breit wie nötig. Wenn man sich dann noch mit dem sizeof-Operator anfreunden kann, klappt's auch mit dem sprintf.
Der Code kracht auf meinem 64-Bit-PC schon mit seg fault. Wahrscheinlich eine Verschwörung der Lügencompiler. Wenn man das machen muss, gibt es passendes in stdint.h: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html
Warum glaubst du eigentlich einen Pointer in einem long und zurück casten zu müssen? Lass den Pointer doch Pointer bleiben.
Walter K. schrieb: > Es geht doch darum, zu hinterfragen was passiert eigentlich: wenn solch > Code mal auf einer Maschine mit 128Bit Adressraumbreite läuft und > Adressen mittels long auf 64Bit gecastet sind! Warum willst Du das wissen? Überhaupt einen Gedanken zu verschwenden, ob wann wo das läuft oder nicht, ist Zeitverschwendung. Es gibt tausend Wege, sich in den Fuß zu schießen. Deiner ist nur einer von vielen.
Tom schrieb: > Der Code kracht auf meinem 64-Bit-PC schon mit seg fault. Wahrscheinlich > eine Verschwörung der Lügencompiler. Nee kein Lügencompiler --- aber ganz sicher Windows ;-)
Walter K. schrieb: > selbstverständlich ist der Code Unsinn! Das haben Beispiele oft so an > sich! Nein, nur die abschreckenden Beispiele, wie man es nicht machen soll.
> nachfolgender Code dürfte ja zukünftig z.B. auf 128Bit Maschinen gegen > die Wand laufen: Da ptr nie initialisiert wird, läuft der bereits jetzt auf allen Maschinen gegen die Wand (wenn nicht, hast du einfach nur Glück gehabt). Sinn ergibt er eh keinen. Selbst der Compiler kotzt sich aus ;-)
Walter K. schrieb: > Es geht doch darum, zu hinterfragen was passiert eigentlich: wenn solch > Code mal auf einer Maschine mit 128Bit Adressraumbreite läuft und > Adressen mittels long auf 64Bit gecastet sind! Dein Denkfehler beruht auf der weit verbreiteten Unsitte, mit Typecasts um sich zu werfen. Weitaus besser wäre es, seinen Code so zu schreiben, daß man ohne Typecasts auskommt und das Umsetzen auf die jeweilige Zielarchitektur dem Compiler zu überlassen. Allerdings sehe ich durchaus, daß es schon jetzt mit der Typsicherheit bei C schlecht bestellt ist, das Herumgeeiere wegen der eigentlich nötigen Integer-Typen und der ebenso nötigen Trennung zwischen Integer-Typen und Text-Typen kennt ma ja - und es sieht nicht danach aus, daß das JEMALS in C wirklich mit dem eisernen Besen ausgekehrt werden wird. Von echten Boolean's ganz zu schweigen. W.S.
Walter K. schrieb: > nachfolgender Code dürfte ja zukünftig z.B. auf 128Bit Maschinen gegen > die Wand laufen: Der läuft auch schon bei gängigen X86_64 Maschinen schief, denn int ist da oft nur 32-bittig. Anderes Beispiel wären 8051 Compiler, dort ist i.d.R. sizeof(void*) = 3 (bytes), weil man so die unterschiedlichen Speichertypen (code, data, xdata) abhandeln kann.
W.S. schrieb: > das Herumgeeiere wegen der eigentlich nötigen Integer-Typen Das existiert nur für Dich, weil Du auch 2018 immer noch nicht bemerkt hast, was mit dem C99-Standard Einzug gehalten hat.
Moin, Voellig OT; meine Lieblingsfehlermeldung des gcc:
1 | echo "main(){ long long long bla=3;}" | gcc -xc - |
2 | <stdin>: In function 'main': |
3 | <stdin>:1:19: error: 'long long long' is too long for GCC |
Gruss WK
Walter K. schrieb: > Frank M. schrieb: >> Warum machst Du sowas? Der Code ist doch kompletter Unsinn?!? > > selbstverständlich ist der Code Unsinn! Das haben Beispiele oft so an > sich! Nur Beispiele, die zeigen, wie man etwas nicht macht. Das tut deins auch. > Es geht doch darum, zu hinterfragen was passiert eigentlich: wenn solch > Code mal auf einer Maschine mit 128Bit Adressraumbreite läuft und > Adressen mittels long auf 64Bit gecastet sind! Mist passiert da, weil man einen Fehler im Programm hat. > Mit der Prozessorbitbreite hat das erst mal gar nichts zu tun! Schon alleine deshalb, weil die Breite eines Zeiger auch nicht der nativen Breite eines Integers der Plattform entsprechen muss. Es darf auch Plattformen geben, wo ein int 128 Bit breit ist und ein Zeiger nur 32 Bit. Oder umgekehrt. Dergute W. schrieb: > <stdin>:1:19: error: 'long long long' is too long for GCC Da musste ich natürlich ausprobieren, was bei "short short" rauskommt, aber da ist die Fehlermeldung viel langweiliger: shortshort.c:19:7: error: duplicate ‘short’
W.S. schrieb: > Dein Denkfehler beruht a Und (nicht nur) dein Denkfehler beruht darauf, nicht zu wissen dass Freitag ist und dann immer die Dümmsten der Dummen irgendwelchen schlecht ausgedachten Schwachsinn als Trollbeitrag hier posten weil sie fachliche Flachpfeifen sind. Also einfach auf solchen Unsinn nicht antworten, dann sterben Trolle ganz alleine.
schade...das wieder einen das Wort mit T erwähnt...in diesem Forum gibt es nicht einen der dumm quatschen muss. anstelle zu helfen..
Timo schrieb: > schade...das wieder einen das Wort mit T erwähnt...in diesem Forum > gibt > es nicht einen der dumm quatschen muss. anstelle zu helfen.. Walter Kollascheck ist nicht mehr zu helfen.
Walter K. schrieb: > int ptr; > > *((unsigned long *) ptr) = malloc(strlen(string) + 1); hier wird ptr uninitialisiert verwendet. Ende der Analyse.
Ma W. schrieb: > Walter K. schrieb: >> int ptr; >> >> *((unsigned long *) ptr) = malloc(strlen(string) + 1); > > hier wird ptr uninitialisiert verwendet. > Ende der Analyse. ptr ist nicht uninitialisiert, ptr ist kein Pointer. Die Zeile ist allerdings mindestens implementation defined und undefined, wenn der Rückgabewert von malloc nicht als int dargestellt werden kann, oder long nicht die gleiche Breite wie int hat.
mh schrieb: > Ma W. schrieb: >> Walter K. schrieb: >>> int ptr; >>> >>> *((unsigned long *) ptr) = malloc(strlen(string) + 1); >> >> hier wird ptr uninitialisiert verwendet. >> Ende der Analyse. > > ptr ist nicht uninitialisiert, ptr ist kein Pointer. Ob Pointer oder nicht, spielt keine Rolle. Ein int als lokale Variable wird genauso wenig initialisiert wie ein Pointer, wenn man das nicht epxlizit tut. > Die Zeile ist allerdings mindestens implementation defined und undefined, > wenn der Rückgabewert von malloc nicht als int dargestellt werden kann, > oder long nicht die gleiche Breite wie int hat. Er schreibt den Rückgabewert von malloc nicht in den int. Er interpretiert den (uninitialisierten) int als Zeiger auf unsigned long und schreibt den Rückgabewert dorthin, wohin dieser zeigt.
Hans schrieb: > Very long and even longer Auf AVR hingegen ist "int" ja eigentlich "rather short". ^^
mh schrieb: > ptr ist nicht uninitialisiert Doch, ist es. Eindeutig. Das sieht natürlich auch der Compiler so.
1 | test.c:6:3: warning: ‘ptr’ is used uninitialized in this function [-Wuninitialized] |
2 | *((unsigned long *) ptr) = malloc(strlen(string) + 1); |
3 | ~^~~~~~~~~~~~~~~~~~~~~~ |
Damit ist das Programm undefiniert und funktioniert auf gar keiner Architektur.
nicht besser? schrieb: > Frank M. schrieb: >> ptr = malloc(strlen(string) + 1); > > Warum nicht sizeof() Wenn schon ein schlechtes Beispiel, dann gleich richtig schlecht...
nicht besser? schrieb: > Frank M. schrieb: > ptr = malloc(strlen(string) + 1); > > Warum nicht sizeof() Ich schrieb doch, dass man einiges optimieren kann. Das war aber nicht die Aufgabe. Daher habe ich den vorliegenden Code einfach 1:1"übersetzt".
Nop schrieb: > Auf AVR hingegen ist "int" ja eigentlich "rather short". Haste Recht. Aber "even longer" war vorher im Amt. W.S.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.