Fehler: The variable is being used without being initialized.
-
Hallo Leute,
ich habe seit kurzem folgende Fehlermeldung wenn ich versuche mein Programm zu kompilieren:
"Runtime-Check Failture #3 - The variable 'sumx' is being used without being initialized."
Meine Deklaration sieht wie folgt aus:
long double ...x,y,z,sumx,sumy,sumz,...;
Das komische ist aber dass ich vor sumx andere Variablen nutze wie z. B. x,y,z:
while (0 == feof( stream ) ) { if ( 3 != fscanf_s( stream, "%Lf %Lf %Lf\n", [b]&x[/b], [b]&y[/b], [b]&z[/b] ) ) { printf ( "Koordinatendatei fehlerhaft\n" ); printf ( "Zeile : %d", n+1 ); return 1; } else n++; }
Hier gibt es komischerweise keine Fehlermeldung bei der Zuweisung.
Weiter unten nutze ich folgende definition:
long double arrx[n+1], arry[n+1], arrz[n+1]
Die Stelle an der sumx das erste mal gebraucht wird und wo der Fehler anscheinend auftritt sieht so aus:
arrx[i] = x; arry[i] = y; arrz[i] = z; sumx += x; sumy += y; sumz += z;
Fragen:
- Wieso meckert er ausgerechnet bei sumx und nicht schon bei x,y,z oder arrx[]?
- Ist es schlechter Stil wenn man die Variablen nicht gleich mit einem Wert belegt?
- Es hat alles wunderbar funktionier bis ich in meinem Visual Studio 2008 an den Compiler Einstellungen rumgespielt habe und nun weiß ich nicht welche Einstellung es war die ich gesetzt habe. Weiß vielleicht jemand weiter?
Danke!
-
darkfate schrieb:
- Wieso meckert er ausgerechnet bei sumx und nicht schon bei x,y,z oder arrx[]?
Du hast &x benutzt, das ist ein fester wert.
darkfate schrieb:
- Ist es schlechter Stil wenn man die Variablen nicht gleich mit einem Wert belegt?
Nein, das sinnlose Belegen ALLER Variablen ist schlechter.
darkfate schrieb:
- Es hat alles wunderbar funktionier bis ich in meinem Visual Studio 2008 an den Compiler Einstellungen rumgespielt habe und nun weiß ich nicht welche Einstellung es war die ich gesetzt habe. Weiß vielleicht jemand weiter?
sumx mit 0 zu belegen wäre die Lösung (das gehört definitiv zu sen nicht-sinnlos-Belegungen).
-
volkard schrieb:
sumx mit 0 zu belegen wäre die Lösung (das gehört definitiv zu sen nicht-sinnlos-Belegungen).
Du hast &x benutzt, das ist ein fester wert
Danke für deine Antwort.
Ich leide hier unter dem Problem dass die Summe tatsächlich auch Null sein kann. Damit würde sich praktisch ein Fehler einschleichen.
Warum hat es vorher funktioniert?
Kann ich den Wert irgendwie mit NULL oder NAN belegen damit ich weiß wenn es Fehler gab?Was meinst du nun mit fester Wert bei &x?
sumx sumx bekommt doch auch einen festen wert.
-
darkfate schrieb:
Kann ich den Wert irgendwie mit NULL oder NAN belegen damit ich weiß wenn es Fehler gab?
Eher nicht. Aber das Summieren klappt doch immer, was soll da geprüft werden?
darkfate schrieb:
Was meinst du nun mit fester Wert bei &x?
scanf kriegt die Adresse von x, das ist ein Wert, den der Compiler sinnvoll rausfinden kann, egal, ob x initialisiert ist oder nicht.
-
volkard schrieb:
darkfate schrieb:
Kann ich den Wert irgendwie mit NULL oder NAN belegen damit ich weiß wenn es Fehler gab?
Eher nicht. Aber das Summieren klappt doch immer, was soll da geprüft werden?
Es gibt einen Fall in dem diese Berechnung automatisch umgegangen werden kann.
Dann wüsste der Nutzer nicht ob diese 0.0 durch eine Fehlberechnung oder durch eine Tasächliche Endsumme von 0.0 zustandekommt.
-
volkard schrieb:
darkfate schrieb:
- Ist es schlechter Stil wenn man die Variablen nicht gleich mit einem Wert belegt?
Nein, das sinnlose Belegen ALLER Variablen ist schlechter.
Das beugt aber sehr vielen Fehlern bei Unklarheit über den Inhalt vor. Man sollte Variablen IMMER initialisieren.
-
TyRoXx schrieb:
Das beugt aber sehr vielen Fehlern bei Unklarheit über den Inhalt vor. Man sollte Variablen IMMER initialisieren.
Bullshit. Das Verdeckt vielleicht Symptome, aber verhindert zugleich die Heilung.
int a=64783678; cin>>a;
Welchen Zweck hat hier die 64783678?
-
darkfate schrieb:
- Wieso meckert er ausgerechnet bei sumx und nicht schon bei x,y,z oder arrx[]?
weil 'sumx' gelesen wird, ohne vorher beschrieben worden zu sein. nicht-initialisierte lokale variablen haben unvorhersehbaren inhalt. beispiel:
int sumx; // sumx hat irgendeinen inhalt ... sumx += 7; // entspricht sumx=sumx+7, compiler meckert, inhalt von sumx ist unbestimmt, daher ist sumx+7 auch quatsch
-
volkard schrieb:
TyRoXx schrieb:
Das beugt aber sehr vielen Fehlern bei Unklarheit über den Inhalt vor. Man sollte Variablen IMMER initialisieren.
Bullshit. Das Verdeckt vielleicht Symptome, aber verhindert zugleich die Heilung.
int a=64783678; cin>>a;
Welchen Zweck hat hier die 64783678?
Das mit der Heilung stimmt schon irgendwie, aber meldet ein Programm auch auf Release solche Fehler? Höchstens mit einem freundlichen ".. hat ein Problem festgestellt und muss beendet werden". Da ist ein Default-Wert doch irgendwie schöner, auch wenn er unter ganz bestimmten Umständen das Finden des Fehlers behindern kann. Dass man bei "int a; cin >> a;" nichts initialieren muss, ist klar. Aber ansonsten bleibe ich bei meiner Verfahrensweise, besser einmal zuviel als einmal zu wenig initialisieren.
-
TyRoXx schrieb:
Dass man bei "int a; cin >> a;" nichts initialieren muss, ist klar.
fein.
TyRoXx schrieb:
Aber ansonsten bleibe ich bei meiner Verfahrensweise, besser einmal zuviel als einmal zu wenig initialisieren.
Nö. Das hängt von der Sprache ab und vom umgebenden Programmierstil. Bei mir ist Deine Verfahrensweise nicht sinnvoll. Aber bei mit gibt es uninitialisierte Variablen praktisch nur direkt vor cin. An anderen Stellen steht immer ein sinnvoller Wert bereit.
Entsprechend schreibi ich nichtdouble r=0,h=0,pi=3.14,g=0,v=0; cin>>r; cin>>h; g=pi*r*r; v=g*h; cout<<v<<'\n';
, sondern
double const pi=3.14; double r; cin>>r; double h; cin>>h; double g=pi*r*r; double v=g*h; cout<<v<<'\n';
Falls doch mal eine Variable uninitialisiert definiert wird, leuchtet das mir wie ein
reinterpret_cast
entgegen als potentiell gefährlicher Code.
-
TyRoXx schrieb:
Aber ansonsten bleibe ich bei meiner Verfahrensweise, besser einmal zuviel als einmal zu wenig initialisieren.
brauchst du doch garnicht. du benutzt doch schon einen guten compiler (oder einen guten debug-mode), der bemerkt, wenn der wert einer nichtinitialisierten variablen verwendet wird.
und falls mal nicht: http://www.splint.org/
-
Mittlerweile habe ich das Projekt neu aufgerollt und den Code umgepastet... scheint auch wieder ohne Initialisierung zu klappen.
Leider habe ich immer noch keine befriedigende Lösung für Startwerte.
0.0 ist wie jede andere Reele Zahl etwas unbefriedigend weil es auch in der Lösungsmenge vorkommen kann.
Es muss doch einen Weg geben um eine Fehlberechnung vorzubeugen.
Gibt es da eine andere Lösung als eine Zahl?Ich könnte auf der Imaginär- und der Realachse einen Wert vorgeben und hoffen dass er nur wirklich wirklich selten vorkommt.
So etwas wie:
complex long double a=4.7622031559045984242551169178169247811744799836995590294248+1.7320508075688772935274463415058723669428052538103806280558*I;
Ein recht unbefriedigendes Ergebnis.. vor allem wenn man es irgendwo dokumentieren muss..
Zumindest sinkt der Prozentsatz dass man zufällig auf diesen Wert kommt auf Nahezu Null.
-
darkfate schrieb:
Mittlerweile habe ich das Projekt neu aufgerollt und den Code umgepastet... scheint auch wieder ohne Initialisierung zu klappen.
Das ist nur Zufall. Der Zugriff auf uninitialisierte Variablen ist undefiniert.
Leider habe ich immer noch keine befriedigende Lösung für Startwerte.
0.0 ist wie jede andere Reele Zahl etwas unbefriedigend weil es auch in der Lösungsmenge vorkommen kann.
Es muss doch einen Weg geben um eine Fehlberechnung vorzubeugen.
Gibt es da eine andere Lösung als eine Zahl?Irgendwie versteh ich gar nicht, wo du da Probleme siehst. Wodurch zeichnet sich denn eine Fehlberechnung aus? Wodurch wird sie verursacht? Wenn du eine dieser Fragen beantworten kannst, dann kannst du diesen Fall doch abfangen. Und falls es auf diese Fragen keine Antwort gibt: Computer verrechnen sich nicht einfach so.
(Jetzt seh ich schon irgendeinen Klugscheißer kommen, der auf mögliche Hardwarefehler verweist.)
-
das kann nur ein hardwarefehler sein.
-
SeppJ schrieb:
Irgendwie versteh ich gar nicht, wo du da Probleme siehst. Wodurch zeichnet sich denn eine Fehlberechnung aus? Wodurch wird sie verursacht? Wenn du eine dieser Fragen beantworten kannst, dann kannst du diesen Fall doch abfangen. Und falls es auf diese Fragen keine Antwort gibt: Computer verrechnen sich nicht einfach so.
Beispiel:
Ich initialisiere die Variable mit 0. Mein Programm erwartet als Eingangsparameter eine Koordinatendatei. Manche Koordinaten werden mitgenommen, manche werden ausgeschlossen. Nachdem alle Schleifen durchgegangen sind will ich entscheiden ob das Ergebnis sinnvoll ist.Bei 0 weiß ich jetzt nicht ob eine Berechnung durchgeführt wurde oder nicht da die Summe ebenfalls Null sein kann. Sie kann praktisch jeden long double Wert annehmen. Ich weiß auch dass ich oben einen Zähler anbringen kann um zu schauen wieviel gerechnet wurde...
Gefragt habe ich eigentlich wie man so etwas eventuell besser lösen kann weil ich damit überhaupt keine Erfahrung habe. Ob ich etwas wie NAN oder NULL zuordnen kann... so müsste ich unten nur nach NAN oder NULL überprüfen.
Sorry war womöglich etwas unglücklich geschrieben.
SeppJ schrieb:
Das ist nur Zufall. Der Zugriff auf uninitialisierte Variablen ist undefiniert.
Hat zumindest bisher immer funktioniert. Ist bestimmt ein Hardwarefehler
-
darkfate schrieb:
SeppJ schrieb:
Das ist nur Zufall. Der Zugriff auf uninitialisierte Variablen ist undefiniert.
Hat zumindest bisher immer funktioniert.
kann garnicht funktioniert haben. auf eine uninitialsierte variable kannste soviel aufsummieren wie du willst, es kommt immer schrott raus.
-
;fricky schrieb:
kann garnicht funktioniert haben. auf eine uninitialsierte variable kannste soviel aufsummieren wie du willst, es kommt immer schrott raus.
Ich kann dir vorschlagen den Intel Compiler herunterzuladen und mit den selben Command Line Argumenten das selbe Stück Code unter Visual Studio 2008 zu compilieren. So doof es auch klingt da es bisher immer funktioniert hat und ich ein C Neuling bin hat es mich nicht gekümmert. Was ich mir gut vorstellen kann ist dass eine der Performanceoptimierungen die Variablen intialisiert.
Mittlerweile habe ich auch den Ort gefunden wo man das regeln kann. Zum einen gibt es unter Runtime Checks den Flag /RTCu für uninitialisierte Variablen. Zum anderen bekomme ich wieder Probleme wenn ich alle Codeoptimierungen im Intel Compiler abschalte.
Gibt es eine kompakte Schreibweise um alle Variablen mit einem Wert zu belegen?
-
darkfate schrieb:
Ich kann dir vorschlagen den Intel Compiler herunterzuladen und mit den selben Command Line Argumenten das selbe Stück Code unter Visual Studio 2008 zu compilieren. So doof es auch klingt da es bisher immer funktioniert...
kann sein, dass dieser compiler alle lokalen variabeln auf 0 setzt, aber das machen die anderen nicht, weil sie's nicht müssen.
Gibt es eine kompakte Schreibweise um alle Variablen mit einem Wert zu belegen?
z.b. könnteste alle variablen in eine struct stecken und dann mit 'memset' alles auf 0 setzen (geht nur mit 0). oder mit einer struct-initialisierung (... = {3,4.8,"hallo"}). sowas ist trotzdem oft sinnlos, weil variablen, auf die irgendwann später als erstes ein schreibzugriff erfolgt, nicht initialisiert sein müssen (wie volkard und so hier auch schon erzählt haben).
-
Ich kann nur empfehlen, eigenen Code ab und zu mal mit einem zweiten oder dritten Compiler parallel zu kompilieren (wenn es geht und wenn man die Möglichkeit dazu hat)
-
abc.w schrieb:
Ich kann nur empfehlen, eigenen Code ab und zu mal mit einem zweiten oder dritten Compiler parallel zu kompilieren (wenn es geht und wenn man die Möglichkeit dazu hat
oder den C-standard lesen ("ISO/IEC 9899:1999 Programming Languages -- C") und verinnerlichen, was aber nicht ganz leicht ist.