Seite 1 von 1

[C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 11:11
von Krishty
Ich schreibe normalerweise const als Postfix: int const * const ist (von hinten nach vorn gelesen) ein konstanter Zeiger auf eine konstante Ganzzahl.

Nun möchte ich den Ausdruck constexpr machen. constexpr impliziert const. Also wird

  int const x = 0;

zu

  int constexpr x = 0;

und

  int const * const x = nullptr;

wird zu

  int const * constexpr x = nullptr;

… und genau hier liegt das Problem: Visual C++ schluckt das constexpr an der Stelle nicht. Wenn ich hingegen ein typedef benutze, à

  using IntConstPtr = int const *;
  IntConstPtr constexpr x = nullptr;


… dann klappt es. Ebenso

  constexpr int const * x = nullptr;

Hat Visual C++ das Parsing verkackt oder geht constexpr nur als Präfix?

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 14:03
von dot
Visual C++ hat recht.

constexpr ist ein specifier (sowas wie friend und inline) und kein qualifier (sowas wie const und volatile). Die grundlegende Struktur einer simple-declaration ist

decl-specifier-seq init-declarator-list;

Specifier wie constexpr und auch der defining-type-specifier (in deinem Fall int const) gehören zur decl-specifier-seq während ein ptr-operator wie * oder & zum declarator im jeweiligen init-declarator in der init-declarator-list gehören.

Mit anderen Worten: int const * constexpr x = nullptr; funktioniert nicht weil der * zum x muss. int const constexpr * x = nullptr; würde funktionieren. IntConstPtr constexpr x = nullptr; funktioniert weil der IntConstPtr Alias die Stelle des defining-type-specifier einnehmen kann.

Fun fact: int; und int const; sind beides valide simple-declarations weil die init-declarator-list optional ist; int*; allerdings nicht weil der * einen init-declarator beginnt...

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 15:02
von Krishty
Also muss ich mich wieder umgewöhnen … wäre ja auch zu schön gewesen :(

Nagut … *schulterzuck* … ich werde wohl alt.

Danke für die Erklärung!

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 17:12
von dot
Krishty hat geschrieben:Also muss ich mich wieder umgewöhnen … wäre ja auch zu schön gewesen :(
Die Sache ist: Sowas wie ein int const * constexpr * x würde keinen Sinn ergeben. Ein "linksbindendes constexpr" analog zu deinem Einsatz von const in deinem Beispiel mit int const * constexpr x würde ebenfalls keinen Sinn ergeben, denn das würde dann ja bedeuten dass das constexpr an den Typ bindet!? Den Typ const zu machen ist aber nicht der Zweck von constexpr. const und constexpr tun einfach zwei fundamental verschiedene Dinge. Nur weil constexpr auf Variablen top-level const impliziert heißt nicht dass constexpr die selbe Semantik hat wie const. Auf Funktionen impliziert constexpr z.B. inline...

constexpr ist kein Qualifier der sich auf einen Typ bezieht sondern es sagt etwas über eine typunabhängige Eigenschaft der deklarierten Entität selbst aus.

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 17:29
von Krishty
Ja; das stimmt natürlich. Ich habe nur mitunter alignas(64) static constexpr char const * const foo[] und brauche kalt eine halbe Minute, zu verstehen, was da überhaupt deklariert wird – und das äußerste const durch constexpr ersetzen hätte die Sache vereinfacht :(

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 17:34
von dot
OK xD

Rein aus interesse: In welchem Kontext macht ein alignas auf einem constexpr Objekt Sinn? :o

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 21:18
von Krishty
Lookup-Tabelle für sin() und Verwandtschaft – die Konstanten passen in eine Cache-Zeile, und da möchte ich nicht riskieren, dass sie auf zwei landen.

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 21:46
von Krishty
P.S.: const reicht in dem Zusammenhang leider nicht. Wenn man in Visual C++ 2017 in einer Funktion etwas static const deklariert, dann wird trotz der Berechnung zur Compile-Zeit eine Referenz zu den CRT-Funktionen _init_thread_epoch() & Co hinzugefügt. Diese Funktionen sollen sicherstellen, dass static-Variablen thread-safe initialisiert werden, obwohl keine Laufzeitinitialisierung stattfinde. Ich hasse das wie die Pest, und man kann es nur umgehen, indem man die Daten entweder aus der Funktion ins globale Namespace schiebt (igitt) oder constexpr nutzt (nicht ganz so igitt).

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 22:20
von dot
Ok, macht Sinn :)

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 14.12.2017, 23:42
von xq
Sehr spannender Thread, ich muss mich unbedingt mal mit constexpr beschäftigen

Und ich muss mal meinen Senf zu

Code: Alles auswählen

alignas(64) static constexpr char const * const foo[]
loswerden: schön, dass ich nicht der einzige bin, der char const * schreibt und nicht const char * :)

Re: [C++] constexpr nur als Präfix möglich?

Verfasst: 15.12.2017, 11:39
von Krishty
Yeah, konsistente Syntax ftw!