Hallo,
Warum kann ich einen struct nicht implizit mit "{ ... }" erzeugen und
direkt als Parameter für eine Funktion verwenden? Ich erhalte immer
"Syntaxfehler: '{'" als Fehler.
Kurzes Beispiel:
1
typedefstruct
2
{
3
inta;
4
intb;
5
}summanden;
6
7
intAddiere(summandenparam)
8
{
9
returnparam.a+param.b;
10
}
Funktionsaufruf:
1
summandentest1={1,2};
2
Addiere(test1);// funktioniert
3
Addiere({4,5});// funktioniert NICHT, warum?
Wo liegt für den Compiler das Problem? Er könnte doch ohne weiteres den
Struct implizit erzeugen und auf den Stack schmeißen, damit die Funktion
ihn nutzen kann... danach interessiert selbiger ja nicht mehr.
Der Hintergrund ist folgender:
Ich habe eine verkettete Liste (STL) der ich in einer
Initialisierungfunktion ziemlich viele Elemente anfügen möchte, die z.B.
Defines sind. also Beispiel:
1
Liste.push_back({"einwert",EINWERT});
Gibt's da eine elegante Lösung, die keine temporäre Erstellung einer
Variable (test1, siehe oben) benötigt?
Vielen Dank vorab.
Eine zweite Funktion, die die Werte "einzeln" entgegennimmt. Für die
eigentliche Funktionalität sollte eine von beiden dann die andere
aufrufen, damit der Code nicht dupliziert wird.
Sven P. wrote:
> Voll am Sinn vorbei, würd ich sagen...
Würde ich nicht sagen. Was Alex suchte, war doch lediglich eine
einfachere Schreibweise, 2 Werte in eine zu erzeugende struct auf dem
Stack zu speichern. Die Schreibweise mit { ... } klappt ja nicht, und
das Makro tut doch nichts anderes, als beide Werte in die struct im
Stack zu speichern. Würde die {..}-Methode funktionieren, käme da
wahrscheinlich genau der gleiche Asm-Code heraus wie mit dem Makro.
Hallo Oliver:
Das war so auch mein erster Gedanke. VC++ 2005 akzeptiert den Code dann
aber trotzdem nicht. Selber Fehler.
Die Idee mit dem Makro funktioniert, hätte ich auch selber draufkommen
können.
Alex Wurst wrote:
> Hallo Oliver:>> Das war so auch mein erster Gedanke. VC++ 2005 akzeptiert den Code dann> aber trotzdem nicht. Selber Fehler.
Klar. Das ist nun mal von der C++ Syntax her so nicht vorgesehen.
> Die Idee mit dem Makro funktioniert, hätte ich auch selber draufkommen> können.
Sie ist trotzdem schlecht.
> Liste.push_back({"einwert", EINWERT});>> Gibt's da eine elegante Lösung, die keine temporäre Erstellung einer> Variable (test1, siehe oben) benötigt?
Deine Liste besteht aus bestimmten Typen.
Verpass diesem Type einen Konstruktor und gut ists.
Mach dir keine Sorgen wegen temporärer Variablen. Wenn du die Funktionen
inline machst, wird der Compiler sie wegoptimieren. Der ist als C++
Compiler darauf getrimmt, solche Fälle zu erkennen.
1
enumUnitTypes{
2
EINWERT,
3
ZWEIWERT,
4
DREIWERT
5
};
6
7
stuctUnits
8
{
9
std::stringtext;
10
UnitTypestype;
11
12
Units(conststd::string&text_,UnitTypestype_)
13
:text(text_),
14
type(type_)
15
{
16
}
17
}
18
19
intmain()
20
{
21
std::list<Units>Liste;
22
23
Liste.push_back(Units("einwert",EINWERT));
24
Liste.push_back(Units("zweiwert",ZWEIWERT));
25
Liste.push_back(Units("dreiwert",DREIWERT));
26
}
Wenn deine struct nicht mehr als aus 2 Werten besteht, ist auch der
Hinweis auf std::pair (wie er weiter oben schon mal gebracht wurde) mehr
als gerechtfertigt. Fang an C++ zu programmieren und nicht 'C mit
Erweiterungen'
>Klar. Das ist nun mal von der C++ Syntax her so nicht vorgesehen.
Das war so auch mein erster Gedanke, aber gcc schluckt es. Sowohl als C
als auch als C++.
>VC++ 2005 akzeptiert den Code dann>aber trotzdem nicht. Selber Fehler.
Grüße an Bill...
Oliver
Oliver wrote:
>>Klar. Das ist nun mal von der C++ Syntax her so nicht vorgesehen.>> Das war so auch mein erster Gedanke, aber gcc schluckt es. Sowohl als C> als auch als C++.
Für C gabs da eine Änderung im letzten Standard, die sich meines Wissens
noch nicht bis C++ durchgerungen hat.
Das der gcc es schluckt wundert mich nicht wirklich.
Dazu muss man wissen, wie Änderungen im Standard durch die Gremien
geboxt werden: Da gibt es jemanden der eine Änderung vorschlägt. Sein
Problem: Er braucht eine kleine Lobby die ihn unterstützt, den das
Gremium ist erst mal konservativ und versucht die Sprache so zu halten
wie sie zur Zeit ist. Ein starkes Argument, welches das Gremium niemals
ignorieren wird, ist allerdings, wenn man einen Compiler vorweisen kann,
der diese Änderung bereits enthält und man so dokumentieren kann, dass
diese Änderung erstens machbar ist und zweitens keine sonstigen
weitreichenden Auswirkungen auf die Sprache hat. Und für diese
Demo-Implementierung wird nun mal der gcc sehr gerne hergenommen. Daher
sollte es nicht verwundern, dass der gcc oft schon Dinge beherrscht, die
noch gar nicht durch die Normungs-Gremien als Sprachstandard abgesegnet
wurden.
Karl heinz Buchegger wrote:
> Ein starkes Argument, welches das Gremium niemals> ignorieren wird, ist allerdings, wenn man einen Compiler vorweisen kann,> der diese Änderung bereits enthält und man so dokumentieren kann, dass> diese Änderung erstens machbar ist und zweitens keine sonstigen> weitreichenden Auswirkungen auf die Sprache hat.
Genau darum habe ich ja am Ende die Binärkonstanten (die mit dem 0b)
bei GCC durchgeboxt. Bei der Standardisierung von C99 ist dieses
Feature vorgeschlagen worden, aber die Rationale erklärt dazu nur
lapidar, dass der Vorschlag abgelehnt wurde ``due to lack of precedent
and application''. Zumindest der erste Punkt (lack of precedent) hat
sich dann also mal erledigt, wenn sich die Damen und Herren das nächste
Mal zusammen setzen. :-) (Natürlich gab es zuvor bereits andere
Compiler aus dem Controllerbereich, die es implementiert hatten, aber
die sind vermutlich den C-Normierern zu popelig, als dass sie die
kennen würden. Zumindest `lack of application' hätte sich damit jedoch
auch erledigt, denn ganz ohne Nachfrage wird das kaum jemand da rein
gebaut haben.)
Vielen Dank, die Lösung mit dem Standardkonstrutkor von Karl-Heinz
scheint mir die eleganteste zu sein. Funktioniert auch einwandfrei!
Vielen Dank für die Antworten!
Jörg Wunsch wrote:
> Genau darum habe ich ja am Ende die Binärkonstanten (die mit dem 0b)> bei GCC durchgeboxt. Bei der Standardisierung von C99 ist dieses> Feature vorgeschlagen worden, aber die Rationale erklärt dazu nur> lapidar, dass der Vorschlag abgelehnt wurde ``due to lack of precedent> and application''.
... was mir ehrlich gesagt völlig unverständlich ist. Jeder der mal
einen Compiler gebaut hat, weiß doch aus dem Stand, dass eine derartige
Erweiterung nun wirklich nicht das große Drama verursachen wird. Im
Grunde könnte man mit dem gleichen Argument auch die Hex-Schreibweise
aus der Sprache verbannen oder noch viel besser die unselige
oktal-Schreibweise (ich wär sogar froh, wenn die aus C bzw. C++
verschwinden würde)
> Mal zusammen setzen. :-) (Natürlich gab es zuvor bereits andere> Compiler aus dem Controllerbereich, die es implementiert hatten, aber> die sind vermutlich den C-Normierern zu popelig, als dass sie die> kennen würden.
:-)
Ich denke mal, die sehen sich auch an, welcher Compiler das ist, ob den
jemand kennt, wie gut er den bisherigen Standard umsetzt udgl.
Wenn ich einen C-Compiler schreiben würde und dem eine Erweiterung
verpasse, dann wird das keinen wirklich interessieren. Bau ich das aber
in den gcc ein, dann hat das gleich ein ganz anderes Gewicht. Nicht
vergessen sollte man auch, dass in der Rationale ja auch Firmenvertreter
sitzen. Die haben natürlich auch ein ganz anderes Interesse: Alles was
nicht unbedingt notwendig ist, erst mal abblocken. Neue Forderungen aus
dem Standard bedeuten für sie ja in erster Linie erst mal Änderungen am
bestehenden Produkt was ja gleichbedeutend mit neuen Fehlern im Compiler
und damit erhöhten Kosten ist.
> Zumindest `lack of application' hätte sich damit jedoch> auch erledigt, denn ganz ohne Nachfrage wird das kaum jemand da rein> gebaut haben.)
Ich hab überhaupt das Gefühl, dass die sich hier eher nach Oben
orientieren als sich mit so Kleinigkeiten, die uns µC Programmieren das
Leben ein klein wenig leichter machen würden, abzugeben. Seien wir uns
ehrlich: Ob es Binärkonstanten gibt oder nicht, interessiert doch
ausserhalb der µC Szene niemanden wirklich.