Der GCC 5.1.0 baut mir den Quelltext, der diesen Schnipsel enthält,
anstandslos, wenn mit -O1 gebaut ist. Wenn mit -O0 gebaut wird, bricht
die Kompilierung ab mit:
1
error: expression in static assertion is not constant
moniert der Der ARM-GCC 5.4.1 zu Recht:
"warning: statement with no effect [-Wunused-value]|"
Was ich nicht verstehe:
a) Wann entscheidet der Compiler, wann was konstant ist? Und
b) Wie bekomme ich den/die Compiler in allen Optimierungsstufen
zufrieden?
Walter T. schrieb:> a) Wann entscheidet der Compiler, wann was konstant ist?
In C sind nur Literale konstant. Dass es bei -O2 funktioniert, ist hier
nur Zufall (dank constant propagation).
Walter T. schrieb:> b) Wie bekomme ich den/die Compiler in allen Optimierungsstufen> zufrieden?
In C:
Zum Ausprobieren kleiner Codeschnipsel gibt es den genialen
Compiler-Explorer von Godbolt: https://godbolt.org/
Man tippt/kopiert einen Quelltext-Schnipsel direkt im Browser ein und
der spuckt sofort den kommentierten ASM-Code auf der Web-Seite wieder
aus oder meckert, wenn er nicht kompiliert werden kann. Man kann die
verschiedensten Compiler auswählen und mit ihren Optionen herumspielen.
Walter T. schrieb:> b) Wie bekomme ich den/die Compiler in allen Optimierungsstufen> zufrieden?
In dem Du Ihm sagst, dass es ein `constexpr` ist. Dann kann er die
Optimierung oben nicht auslassen.
Torsten R. schrieb:> In dem Du Ihm sagst, dass es ein `constexpr` ist.
Was in C++ nicht nötig ist (da kompiliert der gcc das in allen
Optimierungsstufen völlig klaglos), und in C nicht möglich.
Und auch wenn Walter das kleine Detail, in was er nun programmiert, uns
nicht mitteilen möchte, wird es doch C sein.
Das der gcc das in C in den höheren Optimierungsstufen frisst, ist ...
seltsam. Denn wie schon geschrieben wurde, ist ein const in C kein
integral const.
Oliver
Walter T. schrieb:> Der GCC 5.1.0 baut mir den Quelltext, der diesen Schnipsel enthält,> anstandslos, wenn mit -O1 gebaut ist. Wenn mit -O0 gebaut wird, bricht> die Kompilierung ab mit:>> error: expression in static assertion is not constant> static_assert( nOverflowPerPulse >= 2 , " Invalid configuration ");
Das ist seltsam.
Offiziell sollte die Fehlermeldung – unabhängig vom Optimierungslevel –
in C immer kommen und in C++ überhaupt nicht. Möglicherweise ist das ein
Bug in 5.1.0. Der bei mir installierte 8.2.1 verhält sich diesbezüglich
korrekt.
Oliver S. schrieb:> Auf godbolt zeigt auch ein gcc 8.3 das gleiche Verhalten wie der 5.1https://godbolt.org/z/l7550g
Bei mir zeigt der GCC in beiden Versionen das optimierungsabhängige
Verhalten.
Walter T. schrieb:> Bei mir zeigt der GCC in beiden Versionen das optimierungsabhängige> Verhalten.
Ja, jetzt kann ich das Problem auch beim 8.2.1 reproduzieren. Zuvor
hatte ich die Definition von nOverflowPerPulse und das static_assert
außerhalb von main, dann erscheint die Fehlermeldung immer.
Edit:
Ich schätze, diese etwas seltsame Verhalten ist aus folgendem Grund
korrekt:
Nach ISO muss das erste Argument von _Static_assert (und damit auch von
static_assert aus assert.h) eine constant-expression sein:
Eine mit const deklarierte Variable sind normalerweise keine
constant-expression, darf es aber implementationsabhängig sein:
1
An implementation may accept other forms of constant expressions.
Damit ist es kein Fehler, wenn der Compiler die const-Variable in einem
static_assert zurückweist, es ist aber auch keiner, wenn er sie
akzeptiert. Man sollte sich aber beim Schreiben von portablen Code auf
letzteres nicht verlassen.
Hallo,
Oliver S. schrieb:> Denn wie schon geschrieben wurde, ist ein const in C kein> integral const.
Kannst du das mal genauer erklären was das bedeutet?
rhf
Roland F. schrieb:> Hallo,> Oliver S. schrieb:> Denn wie schon geschrieben wurde, ist ein const in C kein integral> const.>> Kannst du das mal genauer erklären was das bedeutet?>> rhf
Es gibt in C keine "echten" zur Kompilierzeit konstante Variablen, mit
denen zb Arrays deklariert werden können. Man muss #define oder eben ein
enum nehmen.
In C++ hingegen schon.
Jan schrieb:> Roland F. schrieb:> Hallo,> Oliver S. schrieb:> Denn wie schon geschrieben wurde, ist ein const in C kein integral> const.> Kannst du das mal genauer erklären was das bedeutet?> rhf>> Es gibt in C keine "echten" zur Kompilierzeit konstante Variablen, mit> denen zb Arrays deklariert werden können. Man muss #define oder eben ein> enum nehmen. In C++ hingegen schon.
was es in C möglich macht, die Adressen von const Objekten zu nehmen.
Daniel -. schrieb:> Jan schrieb:>> Roland F. schrieb:>> Hallo,>> Oliver S. schrieb:>> Denn wie schon geschrieben wurde, ist ein const in C kein integral>> const.>> Kannst du das mal genauer erklären was das bedeutet?>> rhf>>>> Es gibt in C keine "echten" zur Kompilierzeit konstante Variablen, mit>> denen zb Arrays deklariert werden können. Man muss #define oder eben ein>> enum nehmen. In C++ hingegen schon.>> was es in C möglich macht, die Adressen von const Objekten zu nehmen.
Was genau macht das in C möglich?
Yalu X. schrieb:> Man sollte sich aber beim Schreiben von portablen Code auf> letzteres nicht verlassen.
Rant: Warum sollte man das auch? Es gibt doch allerhöchstens einen
einzigen C99-Compiler.