Forum: PC-Programmierung Sprache C - > long oder besser immer long long


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Walter K. (walter_k488)


Lesenswert?

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?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Hans (Gast)


Lesenswert?

Very long and even longer

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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 ;-)

von Walter K. (walter_k488)


Lesenswert?

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!

von Amateur (Gast)


Lesenswert?

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;-)

von Nop (Gast)


Lesenswert?

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.

von Tom (Gast)


Lesenswert?

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

von Der Andere (Gast)


Lesenswert?

Warum glaubst du eigentlich einen Pointer in einem long und zurück 
casten zu müssen?
Lass den Pointer doch Pointer bleiben.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Walter K. (walter_k488)


Lesenswert?

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 ;-)

von Peter D. (peda)


Lesenswert?

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.

von foobar (Gast)


Lesenswert?

> 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 ;-)

von W.S. (Gast)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von Nop (Gast)


Lesenswert?

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.

von Cyblord -. (Gast)


Lesenswert?


von Dergute W. (derguteweka)


Lesenswert?

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

von Rolf M. (rmagnus)


Lesenswert?

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’

von MaWin (Gast)


Lesenswert?

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.

von Timo (Gast)


Lesenswert?

schade...das wieder einen das Wort mit T erwähnt...in diesem Forum gibt 
es nicht einen der dumm quatschen muss. anstelle zu helfen..

von MaWin O. (Gast)


Lesenswert?

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.

von MaWin O. (Gast)


Lesenswert?

Walter K. schrieb:
> int ptr;
>
> *((unsigned long *) ptr) = malloc(strlen(string) + 1);

hier wird ptr uninitialisiert verwendet.
Ende der Analyse.

von mh (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Rad ab (Gast)


Lesenswert?

Hans schrieb:
> Very long and even longer

Linglonger!

https://en.wikipedia.org/wiki/Linglong_Tire

von Rolf M. (rmagnus)


Lesenswert?


von Nop (Gast)


Lesenswert?

Hans schrieb:
> Very long and even longer

Auf AVR hingegen ist "int" ja eigentlich "rather short". ^^

von MaWin O. (Gast)


Lesenswert?

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.

von nicht besser? (Gast)


Lesenswert?

Frank M. schrieb:
> ptr = malloc(strlen(string) + 1);

Warum nicht sizeof()

von Gerd E. (robberknight)


Lesenswert?

nicht besser? schrieb:
> Frank M. schrieb:
>> ptr = malloc(strlen(string) + 1);
>
> Warum nicht sizeof()

Wenn schon ein schlechtes Beispiel, dann gleich richtig schlecht...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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".

von W.S. (Gast)


Lesenswert?

Nop schrieb:
> Auf AVR hingegen ist "int" ja eigentlich "rather short".

Haste Recht.

Aber "even longer" war vorher im Amt.

W.S.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.