internal compiler error: Segmentation fault



  • Bei folgendem Code erhalte ich unter gcc 7.3 den Fehler

    internal compiler error: in is_base_type, at dwarf2out.c:12266
    class X : public Features<X<Features...>> ... {

    template<class DerivedT>
    struct CuriousBase{
    };
    
    template<template<typename> typename... Features>
    class X : public Features<X<Features...>> ... {
     public:
      X(Features... f) : Features<X<Features...>>(f)... {}
    };
    
    int main(){
      auto _x = X<CuriousBase>{};
    }
    

    wo ist das Problem? Oo

    wenn ich den Ctor von X defaulte sagt er ambiguous call, weil das variadic function call ja auch mit 0 Argumenten aufgerufen werden kann

    wenn ich es mit default Parametern versuche, kommt

    template<template<typename> typename... Features>
    class X : public Features<X<Features...>> ... {
     public:
      X(Features... f = Features{}) : Features<X<Features...>>(f)... {}
    };
    

    error: parameter pack ‘f’ cannot have a default argument



  • Mit g++ (SUSE Linux) 8.1.1 20180719 [gcc-8-branch revision 262874]

    g++ -Wall -pedantic x.cpp -c -std=c++17
    x.cpp:5:26: error: expected template-name before ‘<’ token
    class X : public Features<X<Features...>> ... {
    ^
    x.cpp:5:26: error: expected ‘{’ before ‘<’ token
    x.cpp:5:26: error: expected unqualified-id before ‘<’ token
    x.cpp: In function ‘int main()’:
    x.cpp:11:13: error: ‘X’ is not a template
    auto _x = X<CuriousBase>{};
    ^
    x.cpp:11:28: error: invalid use of incomplete type ‘class X’
    auto _x = X<CuriousBase>{};
    ^
    x.cpp:5:7: note: forward declaration of ‘class X’
    class X : public Features<X<Features...>> ... {



  • aufgrund von template code folding hatte ich die template definitonen vergessen in der Darstellung hier. Problem ist natürlich unverändert...



  • x.cpp: In function ‘int main()’:
    x.cpp:12:28: internal compiler error: Speicherzugriffsfehler
    auto _x = X<CuriousBase>{};
    ^
    Please submit a full bug report,
    with preprocessed source if appropriate.

    😉



  • seltsam, wenn ich den custom Contructor entferne, das heißt, nur den implizit generierten default ctor habe, dann compiled es

    Noch eine Frage: Habe kürzlich so ein snippet gesehen

    template <typename T>
    struct Widget : T {
      Widget(T t) : T(std::move(t));
    };
    

    wozu dient es, bei der Konstruktion des Subobjects T, eine Instanz von T an den move ctor zu passen?

    Ist das irgendein Idiom mit tieferem Zweck?



  • cl /Wall x.cpp /c /std:c++latest
    Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26726 for x64
    Copyright (C) Microsoft Corporation. All rights reserved.

    x.cpp
    x.cpp(8): error C3205: argument list for template template parameter 'Features' is missing
    x.cpp(9): note: see reference to class template instantiation 'X<Features...>' being compiled
    x.cpp(8): error C3543: 'unknown-type': does not contain a parameter pack
    x.cpp(8): error C2955: 'CuriousBase': use of class template requires template argument list
    x.cpp(2): note: see declaration of 'CuriousBase'
    x.cpp(12): note: see reference to class template instantiation 'X<CuriousBase>' being compiled
    x.cpp(12): error C2512: 'X<CuriousBase>': no appropriate default constructor available
    x.cpp(12): note: No constructor could take the source type, or constructor overload resolution was ambiguous



  • template<class DerivedT>
    struct CuriousBase{
    };
    
    template<template<typename> typename... Features>
    class X : public Features<X<Features...>> ... {
     public:
      X() = default;
      X(Features<X> ...f) : Features<X>(f)... {}
    };
    
    int main(){
      auto _x = X<CuriousBase>{};
    }
    

    so funktoniert es, allerdings verstehe ich nicht, wieso ich beim ctor nicht X in Abhängigkeit von Features... zu bezeichnen habe, wie es bei der Vererbungsdefinition

    class X : public Features<X<Features...>> ...
    

    gemacht wurde



  • @sewing: ich glaube, @manni66 will Dir durch die Blume mit seinen Antworten (auch) sagen, daß es sinnvoller wäre, wenn Du kompletten Code posten würdest anstatt einzelner Schnipsel.

    @sewing sagte in internal compiler error: Segmentation fault:

    wozu dient es, bei der Konstruktion des Subobjects T, eine Instanz von T an den move ctor zu passen?

    Weil eine Kopie bei der Parameterübergabe reicht, wenn t in Widget(T t) sonst nicht benötigt wird?



  • das ist kompletter code, kannst du so in nen file posten und bauen

    @swordfish sagte in internal compiler error: Segmentation fault:

    Weil eine Kopie bei der Parameterübergabe reicht, wenn t in Widget(T t) sonst nicht benötigt wird?

    ja deshalb der move, aber wieso sollte ich überhaupt eine Instanz einer Klasse an die Klasse selbst übergeben in nem default ctor der subklasse



  • @sewing sagte in internal compiler error: Segmentation fault:

    das ist kompletter code, kannst du so in nen file posten und bauen

    Ich bezog mich auf den ersten Post.

    @swordfish sagte in internal compiler error: Segmentation fault:

    Weil eine Kopie bei der Parameterübergabe reicht, wenn t in Widget(T t) sonst nicht benötigt wird?

    ja deshalb der move, aber wieso sollte ich überhaupt eine Instanz einer Klasse an die Klasse selbst übergeben in nem default ctor der subklasse

    Wo ist da ein default-ctor??



  • verschrieben, in dem custom ctor der subklasse meinte ich

    und auch in meinem ersten post steht komplette code



  • Ich glaube, ich sollte meine Fragen besser strukturieren ; )

    1. Was gibt es für Anwendungsfälle bzw. was wird durch den folgenden Code bezweckt? im custom ctor wird der copy ctor der superklasse aufgerufen...

    template <typename T>
    struct Widget : T {
      Widget(T t) : T(t);
    };
    

    2. Sehe ich das richtig, das der zweite ctor theeoretisch Kopien von Instanzen der Klassen mittels derer X instantiiert wurde, an eben genau die ctors dieser Klassen (Superobjekte von 'X) weiterreichen würde?

    template<class DerivedT>
    struct CuriousBase{};
    
    template<template<typename> typename... Features>
    struct X : Features<X<Features...>> ... {
      X() = default;
      X(Features<X<Features...>> ...f) : Features<X<Features...>>(f)... {}
    };
    
    int main(){
      auto x = X<CuriousBase>{};
    }
    

    3. Mir scheint es aber bedingt durch die Mischung aus CRTP und Mixin in diesem Fall nicht möglich, diesen ctor jemals durch Übergabe von lvalues der jeweiligen Objekte zu verwenden, da beide Klassen class-templates sind und CuriousBase als Argument für den X ctor mit X instantiiert werden müsste, und immer so fort. Liege ich da richtig?

    4. Wo ist der Unterschied zwischen obigem Code und dem hier folgenden? Er kompiliert ebenfalls, jedoch dachte ich, dass man angeben muss, dass X seinerseits wieder ein variadisches class template ist, scheint aber nicht nötig zu sein, oder wo ist der Unterschied zwischen beiden Versionen?

    template<class DerivedT>
    struct CuriousBase{};
    
    template<template<typename> typename... Features>
    struct X : Features<X<Features...>> ... {
      X() = default;
      X(Features<X> ...f) : Features<X>(f)... {}
    };
    
    int main(){
      auto x = X<CuriousBase>{};
    }
    

    5. Mir scheint, die einzige Möglichkeit (ohne Designated Initializers von C++20) im Falle von beispielsweise zwei Klassen die "mixed in" werden sollen, explizit argumente an diese beiden Superklassen zu geben, ist mit diesem Syntax, bei dem lokale Objekte der "mixed-in" Klassen im Ctor angelegt werden, die dann den copy-ctor der jeweiligen Basisklasse aufrufen, ist das korrekt?

    #include <string>
    
    template <template <typename> typename... Features>
    struct X : Features<X<Features...>>... {
      X() = default;
      X(Features<X>... f) : Features<X>(f)... {}
    };
    
    template <typename T>
    struct A {
      A() = default;
      A(int a1, int a2) : a1_{a1}, a2_{a2} {}
    
      int a1_, a2_;
    };
    
    template <typename T>
    struct B {
      B() = default;
      B(std::string b) : b_{b} {}
    
      std::string b_;
    };
    
    int main() {
      auto x1 = X<A, B>{};                               // Ok
      auto x2 = X<A, B>{{1, 2}, {std::string("test")}};  // Ok
      auto x3 = X<A, B>{1, 2, std::string("test")};      // Error
    }
    

    Danke für eure Hilfe


Anmelden zum Antworten