mikrocontroller.net

Forum: Compiler & IDEs Diskussion um NTTP in C++20


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Wilhelm M. (wimalopaan)


Bewertung
2 lesenswert
nicht lesenswert
Die Diskussion um NTTP (non-type template parameter) scheint nun beendet 
zu sein. Leider ist da

https://en.cppreference.com/w/cpp/language/template_parameters

nicht ganz auf dem letzten Stand.

In den Papern P0732, P1185 und nun P1907 wurde die ganze Sache gerade 
gezogen, leider mit dem Ergebnis, dass die Typen der NTTP sog. 
structural sein müssen, was wiederum bedeutet, dass alle Datenelemente 
public sein müssen. Das finde ich schade, weil bspw. auch 
std::chrono::duration damit herausfällt (und auch einige meiner eigenen 
Klassentemplates).
#include <cstdint>
#include <cstdlib>
#include <type_traits>
#include <chrono>
#if __has_include("compare")
# include <compare> 
#endif

template<auto V> struct A{};

#if (__GNUC__ <= 9)
struct B {
    constexpr explicit B(int a) : value{a} {}
private:
    const int value{0};
};
#endif

#if (__GNUC__ > 9)
struct B {
    constexpr explicit B(int a) : value{a} {}
    constexpr auto operator<=>(const B&) const = default;
    // to be structural all members have to be public and structural as well
//private:
    const int value{0};
};
#endif

int main() {
    A<B{0x0042}> a1;
    A<B{0x0042}> a2;
    A<B{0x0815}> a3;

    static_assert(std::is_same_v<decltype(a1), decltype(a2)>);
    static_assert(!std::is_same_v<decltype(a1), decltype(a3)>);
    
    using namespace std::literals::chrono_literals;
    
//    A<1min> a4; // not possible
}

von svedisk ficklampa (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
> Das finde ich schade

Das macht doch nuex, solange das gute C noch da ist.

von Guest (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Ich warte ja noch bis jemand eine Sprache in C++ einbettet die 
Turing-complete die Generierung von C++ - Code erlaubt.
Oder geht das mit Templates jetzt schon ;-)

von Johann L. (gjlayde) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
Guest schrieb:
> Oder geht das mit Templates jetzt schon ;-)

Templates für sich genommen sind Turing-vollständig.

Macht die Sprache(n) aber auch nicht schöner.

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Guest schrieb:
> Ich warte ja noch bis jemand eine Sprache in C++ einbettet die
> Turing-complete die Generierung von C++ - Code erlaubt.

Der Beweis:

http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=0BB30D6BBA62A9F8054337264062C075?doi=10.1.1.14.3670&rep=rep1&type=pdf

Das template-Subsystem formt eine compile-time funktionale Sprache. 
Damit kann man Abbildungen (Funktionen) der Formen:

1) compile-time-constant -> compile-time-constant
2) compile-time-constant -> type
3) type -> compile-time-constant
4) type -> type

durchführen. Wobei man für 1) ganz einfach auch constexpr / consteval 
"normale" Funktionen benutzen kann/sollte. Boost-Hana als 
Meta-Programm-Bibliothek erledigt auch 2) - 3) mit constexpr-Funktionen.

von Heiko L. (zer0)


Bewertung
0 lesenswert
nicht lesenswert
2.Attempt to develop the technology required for compiler and linkers to verify thatuser-defined equality operators are self-consistent and evaluate them, or3.Only allow non-type template parameters of class type for classes which havememberwise equality
If a template argument is a value of class type, then how do we mangle it into symbolnames? If we cannot, then how does the linker tell whether two template arguments ofclass type are the same? By default, class types do not even have a notion of equality.If we disregard unions, we could say that classes are simply compared memberwise for the purposes of template instantiation. However, doing this would break the invariant that &i<a> == &i<b> if and only if a == b : the latter may not even be valid, and if it is then it would only give the same results as the former if the relevant operator== implemented the same memberwise comparison that we used for the purposes of template instantiation.To resolve this question, we must either:
1.Allow the existing invariant to be broken, and accept the complexity and subtletiesadded to the language by doing this, or
2.Attempt to develop the technology required for compiler and linkers to verify that user-defined equality operators are self-consistent and evaluate them, or
3.Only allow non-type template parameters of class type for classes which have memberwise equality

This paper proposes pursuing the last of these options...

Ich kann nicht sagen, dass ich das nachvollziehen könnte.
Was spricht gegen das naive "constexpr operator==, wenn der nicht 
richtig funktioniert ist es halt UB"?

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht lesenswert
Heiko L. schrieb:
> Was spricht gegen das naive "constexpr operator==, wenn der nicht
> richtig funktioniert ist es halt UB"?

Gott bewahre: nicht noch mehr davon!

Ich bin kein Compilerbauer und ich habe großen Respekt vor diesen Mädels 
und Jungs. Deswegen ist meine Antwort hier nur laienhaft:

1) Das bisherige Modell der getrennten Übersetzungseinheiten soll 
beibehalten werden

2) Aus 1) folgt, dass der Linker template-ids vergleichen können muss.

3) Für 2) wird bei NTTP deren Bit-Repräsentation als Wert in die 
template-id verwurschtelt (mangled)

4) Die Bit-Repräsentation eines class-type NTTP ist Summe der 
Bit-Repräsentationen der member.

5) Das ist identisch mit einer Gleichheitsdefinition von class-type 
NTTP, die auf allen ihren membern basiert.

6) Ein op== müsste dazu auf jeden Fall dazu konsistent implementiert 
werden.

7) Man kann 6) für user-defined op= nicht sicher stellen

8) Daher erzwingt man 6) durch den Verzicht auf Klasseninvarianten durch 
all-public member, d.h. der beobachtbare Zustand eines Typs sind alle(!) 
member, daher ist die Gleichheit zweiter Objekte durch einen 
elementweisen Vergleich gegeben.

Bottom-line: man bräuchte eine konsistente Abbildung des Objektzustandes 
(Werte) in eine template-id. Dazu ist für C++23 ein "operator template" 
vorgeschlagen. Wie man für den dann allerdings die Konsistenz mit op== 
bzw. op<=> sicherstellen will, ist mir noch nicht klar. Man läuft dann 
in dasselbe Problem wie bei Java mit equals() und hashCode().

Das ist eine "Lösung", die eben bestimmte Typen ausschließt, aber 
ansonsten in das bisherige Modell passt, ohne neue Schwierigkeiten 
einzubauen.

von Heiko L. (zer0)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Das ist eine "Lösung", die eben bestimmte Typen ausschließt, aber
> ansonsten in das bisherige Modell passt, ohne neue Schwierigkeiten
> einzubauen.

Naja, enttäuschend ist das Ergebnis aber schon. Unter den 
Einschränkungen ist das Feature schon fast nicht zu gebrauchen.
Vielleicht hätte man deswegen von vornherein darauf verzichten und alles 
von Anfang an nur über den operator regeln. Das ganze Problem wäre dann 
nur syntactic sugar. Statt zu schreiben someClass<template_hash(x)> 
hätte man someClass<x> und könnte alles frei überladen.

bottom-line: Das "Feature" werde ich vermutlich nicht nutzen, bis es 
richtig funktioniert, so mit normalen Klassen und so.

Aber danke für die Erklärung.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Bewertung
0 lesenswert
nicht lesenswert
Heiko L. schrieb:
> bottom-line: Das "Feature" werde ich vermutlich nicht nutzen, bis es
> richtig funktioniert, so mit normalen Klassen und so.

Na, so schlimm ist es auch wieder nicht: es sind dann einfach Typen ohne 
Klasseninvarianten bzw. immutables.

Vieles davon könnte man ersetzen durch constexpr-Funktionsparameter. 
Auch dazu gibt es einen Vorschlag.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.