 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Andreas Nicolai Guest
|
Posted: Fri Nov 07, 2003 12:52 pm Post subject: Veränderlicher static Container... |
|
|
Hi!
Guckt Euch mal folgenden Quelltext an:
-----------------------------------
class test {
public:
void func() {};
std::size_t n;
}
void test::func() {
static std::vector<double> tmp(n); // static vector erzeugen
// do some stuff
};
int main() {
test t;
t.n = 10;
t.func(); // static vector wird mit 10 Elementen erzeugt
t.n = 20;
t.func(); // ???? was passiert hier genau?
}
-----------------------------------
Was passiert beim zweiten Aufruf von func? Wird der static vector neu
erzeugt? Oder nur der
Konstruktor aufgerufen, da ja der Speicher für das eigentliche
Vektorobjekt unverändert (static) bleibt?
Erleuchtet mich mal bitte...
Tschüß - Andreas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Fri Nov 07, 2003 3:30 pm Post subject: Re: Veränderlicher static Container... |
|
|
"Andreas Nicolai" <Andreas.Nicolai (AT) web (DOT) de> schrieb:
| Quote: | void test::func() {
static std::vector<double> tmp(n); // static vector erzeugen
// do some stuff
};
Was passiert beim zweiten Aufruf von func?
|
Nichts.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Martin Heibel Guest
|
Posted: Fri Nov 07, 2003 7:24 pm Post subject: Re: Veränderlicher static Container... |
|
|
Andreas Nicolai wrote:
| Quote: | Was passiert beim zweiten Aufruf von func?
"Some stuff" wird getan. |
| Quote: | Wird der static vector neu
erzeugt? Oder nur der
Konstruktor aufgerufen, da ja der Speicher für das eigentliche
Vektorobjekt unverändert (static) bleibt?
Weder noch. Die gesamte Initialisierung (Speicher auf dem "static-Stack" |
resevieren - wie heißt das eigentlich offiziell? - und der
Konstruktoraufruf) wird durchgeführt, wenn die entsprechende Codezeile das
*erste Mal* erreicht wird. Danach wird dieser Code übersprungen.
Damit kann man z.B. einen Counter schreiben, was auch ein schönes, einfaches
Beispiel ist (auch wenn der begriff "Konstruktor" bei int nur bedingt
korrekt ist):
int getCount()
{
static int count(0);
return ++count;
}
int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
<< getCount() << std::endl // 2
<< getCount() << std::endl; // 3
}
| Quote: | Erleuchtet mich mal bitte...
Geh zur Zimmertür, schau nach, ob daneben ein Schalter ungefähr auf halber |
Türhöhe ist und schalte den ein.
Gruß,
Martin
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Christoph Rabel Guest
|
Posted: Fri Nov 07, 2003 10:18 pm Post subject: Re: Veränderlicher static Container... |
|
|
Martin Heibel wrote:
| Quote: | Andreas Nicolai wrote:
Damit kann man z.B. einen Counter schreiben, was auch ein schönes, einfaches
Beispiel ist (auch wenn der begriff "Konstruktor" bei int nur bedingt
korrekt ist):
int getCount()
{
static int count(0);
return ++count;
}
int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
|
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe
implementierungsabhängig ist und genauso 321 wie 123
rauskommen kann.
mfg
Christoph
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Sat Nov 08, 2003 12:01 am Post subject: Re: Veränderlicher static Container... |
|
|
| Quote: | int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe implementierungsabhängig ist
und genauso 321 wie 123 rauskommen kann.
|
Du verwechselst hier ein Problem mit printf bzw Funktionsparametern. Im
obigen Beispiel werden eine Reihe von Funktionen aufgerufen, immer von
links nach rechts.
=> ausgabe(1).endl().ausgabe(2).endl().ausgabe(3).endl();
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Sat Nov 08, 2003 7:26 am Post subject: Re: Veränderlicher static Container... |
|
|
"Markus Breuer" <markus.breuer (AT) gmx (DOT) de> schrieb:
| Quote: | int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe implementierungsabhängig ist
und genauso 321 wie 123 rauskommen kann.
Du verwechselst hier ein Problem mit printf bzw Funktionsparametern.
|
Nein, tut er nicht. (Antworte bitte nicht, bevor Du das einsiehst.
Es nervt.)
MfG
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Martin Heibel Guest
|
Posted: Sun Nov 09, 2003 6:34 pm Post subject: Re: Veränderlicher static Container... |
|
|
Christoph Rabel wrote:
| Quote: | Martin Heibel wrote:
Andreas Nicolai wrote:
Damit kann man z.B. einen Counter schreiben, was auch ein schönes,
einfaches Beispiel ist (auch wenn der begriff "Konstruktor" bei int nur
bedingt korrekt ist):
int getCount()
{
static int count(0);
return ++count;
}
int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe
implementierungsabhängig ist und genauso 321 wie 123
rauskommen kann.
Nach kurzem Nachdenken sehe ich das ein, auch wenn vermutlich kein |
real-existierende Compiler hier etwas anderes tut, als das, was man hier
ganz naiv erwartet.
Ich möchte aber für den OP noch den auf alle Fälle korrekten Code posten:
int main()
{
std::cout << getCount() << std::endl; // 1 Konstruktoraufruf
std::cout << getCount() << std::endl; // 2
std::cout << getCount() << std::endl; // 3
}
Zufrieden?
Gruß,
Martin
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Mon Nov 10, 2003 8:39 am Post subject: Re: Veränderlicher static Container... |
|
|
"Martin Heibel" <m3_DOT_heibel (AT) gmx (DOT) de> schrieb:
| Quote: | int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe
implementierungsabhängig ist und genauso 321 wie 123
rauskommen kann.
Nach kurzem Nachdenken sehe ich das ein, auch wenn vermutlich kein
real-existierende Compiler hier etwas anderes tut, als das, was man hier
ganz naiv erwartet.
|
Was denn? 3-2-1 oder 1-2-3? (Ich habe für beides je einen _sehr_
real existierenden Compiler.) Auch möglich, aber eher ungewöhnlich
wären 2-1-3 oder 1-3-2 oder 2-3-1 ...
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Mon Nov 10, 2003 8:55 am Post subject: Re: Veränderlicher static Container... |
|
|
Markus Schaaf schrieb:
| Quote: | "Markus Breuer" <markus.breuer (AT) gmx (DOT) de> schrieb:
int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe implementierungsabhängig ist
und genauso 321 wie 123 rauskommen kann.
Du verwechselst hier ein Problem mit printf bzw Funktionsparametern.
Nein, tut er nicht. (Antworte bitte nicht, bevor Du das einsiehst.
Es nervt.)
|
Auch auf die Gefahr hin dich zu nerven: die Aufrufeihenfolge ist sehr
wohl definiert und nicht implementierungsabhängig! (siehe posting)
Oder spielst du auf den ++-operator an? Der ist nicht Bestandteil des
o.g. Ausdrucks und wird komplett innerhalb der Funktion verarbeitet. Daß
die Funktion innerhalb eines Ausdrucks mehrfach aufgerufen wird, spielt
keine Rolle.
Falls du meine Meinung nicht teilst, spezifiziere bitte etwas genauer,
was du meinst.
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Mon Nov 10, 2003 10:42 am Post subject: Re: Veränderlicher static Container... |
|
|
Markus Breuer wrote:
| Quote: |
Markus Schaaf schrieb:
"Markus Breuer" <markus.breuer (AT) gmx (DOT) de> schrieb:
int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe implementierungsabhängig ist
und genauso 321 wie 123 rauskommen kann.
Du verwechselst hier ein Problem mit printf bzw Funktionsparametern.
Nein, tut er nicht. (Antworte bitte nicht, bevor Du das einsiehst.
Es nervt.)
Auch auf die Gefahr hin dich zu nerven: die Aufrufeihenfolge ist sehr
wohl definiert und nicht implementierungsabhängig! (siehe posting)
|
Ist sie nicht. Ich vereinfache mal ein wenig um weniger tippen zu muessen.
std::cout << getCount() << getCount();
Da getCount() einen int liefert kommt die Member operator<< Funktion eines
streams zum Zug und der Compiler wandelt obiges um zu:
cout::operator<<( getCount() ).operator<<( getCount() );
Und jetzt ab in den C++Standard:
5.2.2 Function call
1 ... A function call is a postfix expression followed by parentheses containing a
possbily empty, comma separated list of expressions which consitute the arguments
to a function.
Also: ein Funktionsaufruf besteht aus 2 Teilen:
* Postfix expression
* Argument Liste
im Ausdruck
cout::operator<<( getCount() ).operator<<( getCount() );
waere die Postfix expression fuer den 2.ten operator Aufruf
cout::operator<<( getCount() ).operator<<
waehrend die Argument Liste aus
getCount()
besteht.
5.2.2 Function call
8 ... The order of evaluation of the postfix expression and the argument expression
list is unspecified.
es ist also undefiniert, ob zuerst
cout::operator<<( getCount() ).operator<<
oder
getCount()
in Angriff genommen wird.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Christoph Rabel Guest
|
Posted: Mon Nov 10, 2003 4:51 pm Post subject: Re: Veränderlicher static Container... |
|
|
Martin Heibel wrote:
| Quote: | Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe
implementierungsabhängig ist und genauso 321 wie 123
rauskommen kann.
Nach kurzem Nachdenken sehe ich das ein, auch wenn vermutlich kein
real-existierende Compiler hier etwas anderes tut, als das, was man hier
ganz naiv erwartet.
|
Wenn mich mein trübes Hirn nicht täuscht liefert obige Zeile
mit dem gcc 3.1 unter Linux kompiliert 321 und unter Windows
123 (kann auch umgekehrt sein, ist ca. ein 3/4tel Jahr her,
das ich das mal ausprobiert habe)
Das Problem ist also nicht nur akademisch sondern real.
mfg
Christoph
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Martin Heibel Guest
|
Posted: Mon Nov 10, 2003 6:19 pm Post subject: Re: Veränderlicher static Container... |
|
|
Markus Schaaf wrote:
| Quote: | "Martin Heibel" <m3_DOT_heibel (AT) gmx (DOT) de> schrieb:
int main()
{
std::cout << getCount() << std::endl // 1 Konstruktoraufruf
getCount() << std::endl // 2
getCount() << std::endl; // 3
}
Mit dem winzigen Nachteil bei deinem Beispiel, das die
Auswertungsreihenfolge der Funktionsaufrufe
implementierungsabhängig ist und genauso 321 wie 123
rauskommen kann.
Nach kurzem Nachdenken sehe ich das ein, auch wenn vermutlich kein
real-existierende Compiler hier etwas anderes tut, als das, was man hier
ganz naiv erwartet.
Was denn? 3-2-1 oder 1-2-3? (Ich habe für beides je einen _sehr_
real existierenden Compiler.) Auch möglich, aber eher ungewöhnlich
wären 2-1-3 oder 1-3-2 oder 2-3-1 ...
Ok, ich sehe ein, *dass* es so ist, aber jetzt würde mich doch |
interessieren, *warum*. Bei den Parametern *eines* Funktionsaufrufes kann
ich noch verstehen, dass die Stackreihenfolge eine Rolle spielt, aber hier
werden die Rückgabewerte der getCount()-Aufrufe doch sowieso in definierter
Reihenfogle weiterverarbeitet, so dass ich mir nicht vorstellen kann, dass
der Freiheitsgrad für die Optimierung so viel bringt, dass der
Intuitionsmangel vertretbar ist. Ich denke, dass ca. 90% aller
C++-Entwickler hierauf reinfallen würden.
Weiß hier jemand genaueres?
Gruß,
Martin
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Alexander Bartolich Guest
|
Posted: Mon Nov 10, 2003 8:07 pm Post subject: Re: Veränderlicher static Container... |
|
|
begin Martin Heibel:
| Quote: | Ok, ich sehe ein, *dass* es so ist, aber jetzt würde mich doch
interessieren, *warum*.
|
Einen Anhaltspunkt dafür liefert das hier:
void print_all_strings(const char* s, ...)
{
va_list va;
va_start(va, s);
do { cout << s; s = va_arg(va, const char*); } while(s);
va_end(va);
}
In Wirklichkeit landen aber nicht fertige Strings auf dem Stack
(woher sollen die denn kommen?), sondern die Argumente der Stream-
Operatoren samt Argumenten.
Auf diese Weise kann eine Funktion in einer Schleife beliebig
lange Ausgabesequenzen abarbeiten.
| Quote: | [...] doch sowieso in definierter Reihenfogle weiterverarbeitet,
so dass ich mir nicht vorstellen kann, dass der Freiheitsgrad
für die Optimierung so viel bringt,
|
Use the source, Luke.
| Quote: | dass der Intuitionsmangel vertretbar ist. Ich denke, dass ca.
90% aller C++-Entwickler hierauf reinfallen würden.
|
Genau. Und Garbage-Collection macht das Programmieren auch gleich
viel einfacher.
--
Für Google, Tux und GPL!
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Mon Nov 10, 2003 8:55 pm Post subject: Re: Veränderlicher static Container... |
|
|
| Quote: | Ist sie nicht. Ich vereinfache mal ein wenig um weniger tippen zu muessen.
std::cout << getCount() << getCount();
Da getCount() einen int liefert kommt die Member operator<< Funktion eines
streams zum Zug und der Compiler wandelt obiges um zu:
cout::operator<<( getCount() ).operator<<( getCount() );
Und jetzt ab in den C++Standard:
5.2.2 Function call
1 ... A function call is a postfix expression followed by parentheses containing a
possbily empty, comma separated list of expressions which consitute the arguments
to a function.
Also: ein Funktionsaufruf besteht aus 2 Teilen:
* Postfix expression
* Argument Liste
im Ausdruck
cout::operator<<( getCount() ).operator<<( getCount() );
waere die Postfix expression fuer den 2.ten operator Aufruf
cout::operator<<( getCount() ).operator
waehrend die Argument Liste aus
getCount()
besteht.
5.2.2 Function call
8 ... The order of evaluation of the postfix expression and the argument expression
list is unspecified.
es ist also undefiniert, ob zuerst
cout::operator<<( getCount() ).operator
oder
getCount()
in Angriff genommen wird.
|
Danke für die ausführliche Erläuterung, mir ist die Argumentation jetzt
klar geworden. Für die Streammanipulatoren (endl,setw,...) trifft o.g.
aber nicht zu, oder sehe ich das falsch. Diese werden ja nicht als
Argument verwendet, sondern sind nur ein weiterer postfix Ausdruck.
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Immanuel Albrecht Guest
|
Posted: Mon Nov 10, 2003 9:09 pm Post subject: Re: Veränderlicher static Container... |
|
|
Martin Heibel <m3_DOT_heibel (AT) gmx (DOT) de> wrote in
news:bool7r$u76$1 (AT) online (DOT) de:
| Quote: | Ich denke, dass ca.
90% aller C++-Entwickler hierauf reinfallen würden.
|
Ja, absolut. Aber warum sollte sich eine Programmiersprache von einem
Durchschnittsmenschen leiten lassen? C++ erhebt nicht den Anspruch, fool-
proof zu sein. Und das finde ich eingentlich auch ganz gut, denn sonst
müsste man noch eine ganze Menge anderer Zugeständnisse machen, die dann
dazu führen würden, dass C++ nicht mehr die Sprache wäre, weshalb sie so
populär geworden ist^.
JM2C
^: Jaja, ich weiß. Eigentlich programmiert man ja in COBOL.
--
http://xrxixpx.rip-productions.de
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|