PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Visual Studio 2005: Gültigkeitsbereich von Variablen


pippo
2006-11-16, 22:31:14
Hab mir grad auf ner neuen Festplatte VS 2005 installiert und wollte an meinem Programm weiterarbeiten, das ich bisher in VS 2003 geschrieben hatte. Folgender Code:

void Funktion xyz (...) {
for(unsigned short int i=0; i<String_anz; ++i) String.push_back(i);
...

for (i=0; i<String.size(); i++){
...
}
}
...cdaten.cpp(118) : error C2065: 'i': nichtdeklarierter Bezeichner

Warum zum ... wird in der 2. for-Schleife die Variable i neu definiert werden? Hat der neue Compiler andere Gültigkeitsbereiche? Kann man das irgendwie ändern?

Trap
2006-11-16, 22:39:20
Variablen die in einem for deklariert werden sind nur innerhalb des for gültig. Das ist in C++ schon immer so, manche Compiler haben das aber falsch gemacht.

Keine Ahnung ob man das falsche Verhalten in VS2005 irgendwie anschalten kann.

pippo
2006-11-16, 22:57:41
Falsch? So lernen wir es im Studium und haben bis jetzt alle Programme jedem Visual Studio so geschrieben.

Begründung von der Professorin: Die Definition und Initialisierung geschieht noch ausserhalb der for-Schleife

Trap
2006-11-16, 23:10:03
Ist trotzdem falsch. In C gilt das mit dem Weiterbestehen der Variablen, im C++ Standard steht aber immer schon, dass die Variablen nur im Body der Schleife gültig sind.

Siehe 6.5.3 im C++ standard draft (draft deshalb, weil die fertige Version nicht frei verfügbar ist):
http://www.csci.csusb.edu/dick/c++std/cd2/stmt.html

pippo
2006-11-16, 23:23:20
Ok, dann glaub ich das auch noch ;)

Aber wenn das so weitergeht, dann kommt VS 2005 wieder runter. Diese ganzen Definitionsfehler werden jetzt nicht alle auf einmal angezeigt sondern bei jedem kompilieren 1 neuer. Wo steckt da der Sinn dahinter?

Neomi
2006-11-17, 00:18:14
Projektsettings
-> Configuration Properties
-> C/C++
-> Language
-> Force Conformance in For Loop Scope

Die Option ist per Default an, du kannst sie aber ausschalten und damit das alte (aber trotzdem noch falsche) Verhalten zurückerlangen.

Coda
2006-11-17, 00:44:33
Wo steckt da der Sinn dahinter?

Der Parser kommt eben in einen Zustand an dem er nach dem Fehler nicht mehr weiterarbeiten kann, deshalb gibts nicht alle Fehlermeldungen auf einmal. Ich finds übrigens echt bedauerlich wenn Leute dann MS noch versuchen hier einen Fehler anzudrehen, wenn sie einen standardkonformen Compiler ausliefern.

Und das man so einen Müll noch beigebracht bekommt... naja ich verkneif mir mal jeden Kommentar...

AtTheDriveIn
2006-11-17, 01:16:32
Falsch? So lernen wir es im Studium und haben bis jetzt alle Programme jedem Visual Studio so geschrieben.

Begründung von der Professorin: Die Definition und Initialisierung geschieht noch ausserhalb der for-Schleife

Deinem Prof gehört auf die Füße getreten. ;)

pippo
2006-11-17, 09:39:52
Der Parser kommt eben in einen Zustand an dem er nach dem Fehler nicht mehr weiterarbeiten kann, deshalb gibts nicht alle Fehlermeldungen auf einmal. Ich finds übrigens echt bedauerlich wenn Leute dann MS noch versuchen hier einen Fehler anzudrehen, wenn sie einen standardkonformen Compiler ausliefern.

Und das man so einen Müll noch beigebracht bekommt... naja ich verkneif mir mal jeden Kommentar...
Da magst du ja Recht haben, aber ich habs nunmal so gelernt :rolleyes:

Der Compiler von VS 2003 hat damals aber auch nicht abgebrochen, nur weil ne Variable nicht definiert war. Da wurden schön alle Fehler auf einmal aufgelistet und nicht bei jedem kompilieren ne neue

Coda
2006-11-17, 10:19:28
Ich habs dir doch erklärt. Wenn der Compiler in eine Situation gerät, bei der er nicht mehr sinnvoll weiterarbeiten kann, dann muss er abbrechen.

Wenn du später mal Compilerbau hörst, wirst das auch noch merken.

ScottManDeath
2006-11-17, 11:38:33
Deinem Prof gehört auf die Füße getreten. ;)

Bestenfalls. Angemessen wäre Kryptoniteinlauf.:mad:

Bin ich froh das VS2k5 das per default auf standard konform hat. Beim VS2k2 hab ich immer {} um meine for Schleifen machen müssen, damit die Variablen lokal waren. Die Option umstellen ging nicht, da ein Teil des Codes vom unkorrekten Verhalten ausgegangen war.

pippo
2006-11-17, 12:08:59
Ich habs dir doch erklärt. Wenn der Compiler in eine Situation gerät, bei der er nicht mehr sinnvoll weiterarbeiten kann, dann muss er abbrechen.

Wenn du später mal Compilerbau hörst, wirst das auch noch merken.
Compilerbau werd ich zum Glück nie anhören müssen. Was VS 2005 hier macht ist doch Schwachsinn von der feinsten Art. Nur weil irgendwo ne Variable nicht definiert ist, kann er doch schonmal den Rest vom Code ansehen, ob nicht sonstwo irgendeine Variable nicht definiert ist oder sonstwas. Das hat bis jetz jedes VS gemacht.

Kann doch nicht angehn, dass ich da 100x kompilieren muss.

Neomi
2006-11-17, 12:44:11
Was VS 2005 hier macht ist doch Schwachsinn von der feinsten Art. Nur weil irgendwo ne Variable nicht definiert ist, kann er doch schonmal den Rest vom Code ansehen, ob nicht sonstwo irgendeine Variable nicht definiert ist oder sonstwas. Das hat bis jetz jedes VS gemacht.

Das, was du hier anmeckerst, machen auch andere Compiler nicht besser. Du wirfst verschiedene Fehler und daraus resultierend verschiedene Verhaltensmuster der Compiler in einen Topf. Unterschiedliche Identifier, die nicht definiert sind, werden auch in VS 2005 je einmal angemeckert, gleiche Identifier (wie eben die verbreitete Laufvariable i) auch in älteren Versionen nur einmal. Der Compiler kann nicht wissen, in welchem Scope i deklariert worden wäre, das könnte ja auch global gewollt sein. Und 12000 Fehlermeldungen für eine einzige fehlende Deklaration (eine fehlende Definition würde erst dem Linker auffallen) würdest du auch nicht wollen.

Fazit: beschwer dich beim Professor, denn der macht es falsch und VS 2005 macht es richtig. Oder schalte das korrekte Verhalten einfach ab, weiter oben habe ich schon beschrieben wie das geht.

pippo
2006-11-17, 14:01:08
VS 2003 hat jedes i angemeckert, das nicht definiert war. Das weiß ich so sicher, weil mir das oft genug passiert ist, dass ich z.B. die 1. Schleife einer Funktion gelöscht hab und somit alle folgenden i nicht mehr definiert waren.

Aber VS 2005 zeigt mir ja jetz nicht mal an, wenn in einer anderen Schleife die Variable j oder k nicht definiert ist. Erst wenn ich i definiere und neu kompiliere bringt er mir die Fehlermeldung, dass auch k in der nächsten Schleife nicht definiert ist

Coda
2006-11-17, 15:54:41
VS 2003 hat jedes i angemeckert, das nicht definiert war. Das weiß ich so sicher, weil mir das oft genug passiert ist, dass ich z.B. die 1. Schleife einer Funktion gelöscht hab und somit alle folgenden i nicht mehr definiert waren.

Dann stell da mal das konforme Verhalten ein (ja die Option gibts auch in 2003, und eigentlich sollte sie auch standardmäßig an sein wie in 2005).

muhkuh_rs
2006-11-17, 19:55:48
VS 2003 hat jedes i angemeckert, das nicht definiert war. Das weiß ich so sicher, weil mir das oft genug passiert ist, dass ich z.B. die 1. Schleife einer Funktion gelöscht hab und somit alle folgenden i nicht mehr definiert waren.


Das zeigt auch sehr schön wie nervig Compiler sind, die ein solches Verhalten bei for-Schleifen zeigen.

Gast
2006-11-17, 20:33:33
Ich finds übrigens echt bedauerlich wenn Leute dann MS noch versuchen hier einen Fehler anzudrehen, wenn sie einen standardkonformen Compiler ausliefern.
*Hustenanfall*
Also der aktuelle Intelcompiler ist da noch wesentlich standardkonformer als der MS Compiler. Wenn man da sieht welcher Code noch von MS compiliert wird, fragt man sich manchmal echt, was die sich dabei gedacht haben.

MikeB
2006-11-17, 23:05:43
Deinem Prof gehört auf die Füße getreten. ;)

Und zwar ganz gewaltig !

VS5.0/6.0 sind richtig Grütze was dieses Verhalten angeht.

Sowas wie:


for(int i = 0;i < 5;i++)
MachWas();
for(int i = 0;i < 6;i++)
MachWas2();


Compiliert der nicht.... ;D Absoluter C++ standard.


{
for(int i = 0;i < 5;i++)
MachWas();
}
{
for(int i = 0;i < 6;i++)
MachWas2();
}


Nur so compilieren diese "Drecks"-Dinger das. Ganz schön lästig.

VS6.0 hat wenigstens die Option schon es richtig zu machen, bei VS5.0 keine Chance das zu compilieren.

Achja, was soll eigentlich "unsigned short int" sein ? Was nu, short oder int ?

Michael

Coda
2006-11-17, 23:13:42
Also der aktuelle Intelcompiler ist da noch wesentlich standardkonformer als der MS Compiler. Wenn man da sieht welcher Code noch von MS compiliert wird, fragt man sich manchmal echt, was die sich dabei gedacht haben.

Kannst du mal ein konkretes Beispiel nennen? Das wäre mir nämlich neu.

MikeB
2006-11-17, 23:22:54
Kannst du mal ein konkretes Beispiel nennen? Das wäre mir nämlich neu.

VS2003 (VS7.1) kompiliert folgendes:


for(int i = 0;i < 5;i++)
MachWas();
i = 2;
for(int i = 0;i < 6;i++)
MachWas2();


;D

Mit VS2005 bin ich nicht so vertraut...

Michael

Coda
2006-11-17, 23:37:38
VS2003 (VS7.1) kompiliert folgendes:

Tut es nicht, wenn man die Compilerflags auf konform setzt (ich bin mir eigentlich ziemlich sicher, dass das der Default war).

MikeB
2006-11-17, 23:46:29
Tut es nicht, wenn man die Compilerflags auf konform setzt (ich bin mir eigentlich ziemlich sicher, dass das der Default war).

Ich hoffe mal, dass ich nicht wieder Sachen durcheinander bringe, wie hier vielleicht VS6.0/7.1... :rolleyes:

Wer will bei sovielen Compilern noch den Durchblick behalten ?

Hab den Compiler grad nicht zur Hand...

Macht immer richtig Spass ein grosses Projekt komplett durch zu arbeiten bei jedem Comilerwechsel...

Michael

Coda
2006-11-17, 23:51:00
Also ab .NET 2003 war Visual C++ eigentlich so gut wie komplett konform.

.NET 2002 und 6.0 waren da noch schlimm, weil sie vor allem keine partielle Template-Spezialisierung konnten.

Und ich glaube .NET 2002 hatte auch noch die Flag auf nicht-konform, da magst du recht haben.

MikeB
2006-11-17, 23:57:08
Muss ich Montag nochmal checken, hab hier zuhause nur den VS5.0... :eek:

Xmas
2006-11-18, 00:25:44
Achja, was soll eigentlich "unsigned short int" sein ? Was nu, short oder int ?
short ist lediglich eine Kurzform für short int.

MikeB
2006-11-18, 00:39:07
Hmm, hab nie Informatik studiert...

Gast
2006-11-18, 00:55:40
Glaub mir, sowas lernst da auch nicht ;)

pippo
2006-11-18, 12:13:49
VS2003 (VS7.1) kompiliert folgendes:


for(int i = 0;i < 5;i++)
MachWas();
i = 2;
for(int i = 0;i < 6;i++)
MachWas2();


Blöde Frage, aber was passt an dem Code nicht?

MikeB
2006-11-18, 12:16:11
Die Variable "i" sollte ausserhalb der for-Schlaufe garnicht definiert sein, also sollte "i=2" einen Fehler geben.

Kabelsalat
2006-11-18, 12:18:00
In der Zeile "i = 2;" ist i eigentlich nicht definiert, da die vorige Definition nur innerhalb der for-Schleife Gültigkeit haben sollte! ... und sollte die Definition über die for-Schleife hinaus gültig sein, müsste der Compiler spätestens in der darauffolgenden Zeile meckern, da in diesem Fall i im selben Gültigkeitsbereich erneut deklariert würde.

pippo
2006-11-18, 12:19:40
Achso, ja. Jetz kapier ichs. VS 2003 kompiliert das auch Standardmäßig, da hast du Recht

Coda
2006-11-18, 12:31:16
Achso, ja. Jetz kapier ichs. VS 2003 kompiliert das auch Standardmäßig, da hast du Recht

Das werd ich später ausprobieren. Ich behaupte dass das nur in 2002 so ist.

pippo
2006-11-18, 12:38:47
Auf dem PC von meinem Dad läuft noch VS 2003 und da läufts genauso wie bei mir damals. Aber probiers aus ;)

MikeB
2006-11-18, 13:13:44
Das werd ich später ausprobieren. Ich behaupte dass das nur in 2002 so ist.

Gut möglich, ist das der VC6.0 ?

muhkuh_rs
2006-11-18, 13:13:48
Visual C++.NET 2003/2005 haben noch andere Merkwürdigkeiten. Z.B. gehen Umlaute in Variablennamen durch.
Bei 2005 ist dann noch so ein fieser Bug, der bei iostreams ein Komma nicht als Trenner von Integern akzeptiert, obwohl global "C" als locale gewählt ist. Was ich da geflucht habe.

Gast
2006-11-18, 14:45:06
Gut möglich, ist das der VC6.0 ?

Okay, hattest recht, bei 2003 ist die Einstellung noch falsch per default.

Gast
2006-11-18, 15:29:21
Kannst du mal ein konkretes Beispiel nennen? Das wäre mir nämlich neu.
Versuch mal ein größeres Projekt, dass mit nur mit VS entwickelt mit dem Intelcompiler zu kompilieren. Du wirst hunderte Warnings und Errors kriegen.

Was zum Beispiel sehr toll ist, dass der MS nur ein Warning ausspuckt, wenn nicht alle Pfad einen Rückgabewert haben. Rückgabewert ist dann einfach undefiniert. Damit findet man zB in der ID-Mathelib ein paar sinnlose Funktionen, die offensichtlich nur zur Signaturbildung gedacht sind und mit MS Compiler ohne Warning durchlaufen. Der Intelcompiler kriegt bei denen nen Herzinfarkt.
Oder z.B. "i = i + 5;" bei undefiniertem i. Das wirft nichtmal ein Warning. Bei voller Optimierung wieder undefinierter Wert. :up:

ScottManDeath
2006-11-18, 19:57:49
Visual C++.NET 2003/2005 haben noch andere Merkwürdigkeiten. Z.B. gehen Umlaute in Variablennamen durch.
Bei 2005 ist dann noch so ein fieser Bug, der bei iostreams ein Komma nicht als Trenner von Integern akzeptiert, obwohl global "C" als locale gewählt ist. Was ich da geflucht habe.

Das mit den Umlauten liegt daran, dass Unicode Souce Code unterstützt wird. In der ersten Phase der Übersetzung wird alles was nicht ASCII ist durch Esacpe Zeichen ersetzt, in der Form \uxxxx bzw \uxxxxxxxx.

Damit ist VC dann Standard konform in dieser Hinsicht =)