CPP warum stürtzt das ab?

Fragen zu allen anderen Programmiersprachen.
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Da man scanf so alles mögliche übergeben kann, braucht es
auch keine Warnung zu geben, da durch das '...' alles richtig ist.
@Danilo
scanf erwartet schließlich einen zeiger, egal in welcher Form und die Variable "wert" wurde nirgendwo als Zeiger initialisiert. Genau das hätte eine Warnung verursachen können. Na ja, dieser Compiler ignoriert es also, oder mann mus sowas wie -Wall Parameter übergeben damit er dies beachtet.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

MARTIN hat geschrieben:scanf erwartet schließlich einen zeiger,
Das ist falsch. scanf erwartet keinen Zeiger sondern beliebige
Argumente - egal welchen Typs:

Code: Alles auswählen

int scanf(const char *format, ...);
Die Deklaration von scanf sagt nichts von Zeigern.

Letztendlich braucht scanf intern nur eine Adresse in Form
einer Zahl.
Folgender Code ist bei dieser Deklaration also völlig legal:

Code: Alles auswählen

scanf("%f", 12345);
Hier übergebe ich eine Speicheradresse in Form einer Zahl,
und an dieser Adresse soll scanf den eingelesenen Floatwert
ablegen.

Auf Systemen mit ungeschützten und festen Speicherbereichen
ist das sogar ein muß.
Denke nur mal an den C64, dort hat man dauernd mit festen
Adressen gearbeitet. Auf embedded Systemen wird das teilweise
bestimmt noch genauso sein.
Da C platformunabhängig ist, muß das ja auch möglich sein -
auf Windows crasht der obige Code natürlich, solange man auf
die Adresse "12345" keinen Zugriff hat.
MARTIN hat geschrieben:egal in welcher Form und die Variable "wert" wurde nirgendwo
als Zeiger initialisiert.
Genau das hätte eine Warnung verursachen können.
Ja, **können**.

Das ist aber kein Teil der Spezifikation und wird somit nicht
gefordert.
In dem einen Beispiel vorhin siehst Du das ich ein 'unsigned long'
an scanf übergebe, und das ist durch '...' völlig legal.
Ein 'unsigned long' ist auch kein Zeiger, genauso wie ein 'float'.
Das u-long enthält in meinem Beispiel nur zufällig die Speicheradresse
des floats, weshalb es auch korrekt funktioniert.

Laut der Deklaration von scanf mit '...' ist es also egal ob man
ein long, float, &long, &float, long* oder float* übergibt.

Der Compiler kann, *wenn er möchte*, die Formatcodes und
die übergebenen Argumente überprüfen und dann eine Warnung
ausgeben.
Einen Fehler darf er aber nicht werfen, da laut Deklaration
alle Argumenttypen erlaubt sind.

Das ursprüngliche Problem (vergessen des Adressoperators '&')
ist ein reiner Programmierfehler, da es eben auch erlaubt ist
float und long etc. direkt zu übergeben. Die Deklaration von
scanf erwartet eben nicht explizit einen Zeiger.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Das ist falsch.
Und was ist das ?
12345
kein Zeiger ?
Doch einen Zeiger der auf Adresse 12345 zeigt.
Aber damit keine Missverständnisse aufkommen, mit dem zeiger meine ich etwas was Adress einer Speicherstelle beinhaltet, und nicht was als Zeiger deklariert wurde, also z.B char *zeiger.
Auf embedded Systemen wird das teilweise
bestimmt noch genauso sein.
Ja, ist auch so.Wer schon mikrocontroler programiert hat, weiss es.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

MARTIN hat geschrieben:Aber damit keine Missverständnisse aufkommen, mit dem zeiger meine ich etwas was Adress einer Speicherstelle beinhaltet, und nicht was als Zeiger deklariert wurde, also z.B char *zeiger.
Das klang bei Dir so als wenn Du einen Zeigertyp meinst.

Wie ich in einem Beispiel schon zeigte:

Code: Alles auswählen

   float wert;
   unsigned long p = (unsigned long)&wert;
   scanf("%f", p);
Hier wird ein unsigned long an scanf übergeben, so wie das
dllfreak2001 mit dem float gemacht hatte - also ohne '&'.

Mir ging es nur darum das dies völlig legal und korrekt ist,
da dllfreak2001 meinte es sei ein Fehler in VC++.
Eigene Fehler passieren jedem. Dann sollte man sie aber
einsehen und nicht auf eine Sprache oder Compiler schieben.

Damit sollte das ja jetzt jeder verstanden haben, also können
wir das Thema auch abhaken... ;)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
dllfreak2001
Beiträge: 2925
Registriert: 07.09.2004 23:44
Wohnort: Bayern

Beitrag von dllfreak2001 »

Klar das man dort keinen Wert übergeben darf wo
eigentlich ein Zeiger verlangt wird.
Ich meinte mit dem Fehler eher MS VC++6.0.
Der wird höllisch instabil schmiert sogar ab, das hatte ich sonst noch nie.
Mich wundert halt das so eine teure Software bei so einem Fehler in der
Programmierung gleich den Geist aufgibt.
Ich glaube das der Debugger zumindest durchhalten sollte.
I´a dllfreak2001
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

dllfreak2001 hat geschrieben:Mich wundert halt das so eine teure Software bei so einem Fehler in der
Programmierung gleich den Geist aufgibt.
Ich glaube das der Debugger zumindest durchhalten sollte.
Vielleicht solltest Du auch mal auf eine neuere Version
upgraden. Version 6 ist schon uralt.

Bei C++ sollte man auch Exception Handling verwenden
um so Fehler abzufangen und das Programm nicht einfach
crashen zu lassen. Dafür ist es ja schließlich da. ;)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten