G++4.8: internal compiler error: Segmentation fault (program cc1plus)



  • Vollständigen Code bitte. Erfahrungsgemäß hat die Stelle, an der Compiler aussteigt, meistens nichts mit dem zugrundeliegenden Problem zu tun.

    Der nächste Schritt wäre die Verwendung eines Debugbuilds von gcc.



  • knivil schrieb:

    Tja, irgendwo hantierst du mit Pointern herum, die auf ungünstigen Speicher zeigen

    Ach, dadurch stuerzt aber der Kompiler nicht ab. Dennoch sollte das bei einem korrekten C++-Programm nicht passiere.

    Oh, mein Fehler.
    Der Compiler hat nen SegFault, nicht das Programm.
    Schande über mich.



  • Ich brings net auf die Reihe Clang 3.3 zu installieren 😑

    Ich mach alles wie hier beschrieben, jedoch ab dem Punkt

    ../llvm/configure --prefix=/usr/clang_3_3 --enable-optimized --enable-targets=host
    

    bekomme ich folgendes gegen den Kopf geworfen:

    configure: error: Selected compiler could not find or parse C++ standard library headers.  Rerun with CC=c-compiler CXX=c++-compiler ./configure ...
    

    Und selbst wenn ich die Variablen CC und CXX setze, kommt immer noch die gleiche Fehlermeldung. Auch das hier hab ich vergeblich befolgt.

    Betrübt vorm Rechner sitzend,
    Hohe Berge und saftige Wiesen.



  • Also unter Fedora/Linux habe ich einfach nur yum install clang gemacht.



  • knivil schrieb:

    Also unter Fedora/Linux habe ich einfach nur yum install clang gemacht.

    Klar, ich auch, jedoch gibts bei meinem Ubuntu da nur die clang Version 3.0, und die versteht ein Haufen C++11-Features nicht - unter anderem kennt die den <type_traits> -Header nicht, von dem ich intensiv Gebrauch nehme.



  • Auch schon mal mit den "Clang Binaries for Ubuntu-12.04/x86 (67M)" von der Downloadseite probiert?



  • binni schrieb:

    Auch schon mal mit den "Clang Binaries for Ubuntu-12.04/x86 (67M)" von der Downloadseite probiert?

    Ja, jetzt eben, aber da muss ich die gesamte libc++ kompilieren und da weiß ich jetzt nicht genau wie ich das anstellen soll... Abgesehen davon bezweifle ich, dass clang3.2 das C++11-Feature "Inheriting Constructors" unterstützt was wiederum nach einem großen Umschreiben meines Programmes riecht.

    Abgesehen davon habe ich operator<< Mal auskommentiert und die Klasse so benutzt und das letzte bisschen Funktionalität rausgekitzelt - alles hat glatt funktioniert, bis ich dann den Operator mitkompiliere, dann krachts.

    Neben der title.hpp gibts auch noch eine entry.hpp (für einen Menüeintrag), bei dem die gleiche Leier vorliegt. Mit operator<< machts Bum und ohne läufts absolut einwandfrei.

    *schnief*
    Grüße.



  • btw, wenn ich (grad aus purer Freude mal getestet) operator>> statt operator<< verwende, funktionierts ganz prächtig.

    Nur dass std::cout >> mytitle; echt das allerletzte ist 😃



  • Tjo, nachdem ich nun weiß womit der G++ nicht klar kommt und es ausgerechnet von der is_printable<> -Klasse stammt muss ich nun wohl oder über meine Identität verraten 😃 (tu ich immer um potenziellem Flaming aus dem Weg zu gehen [falls ich denke, dass ich ne dumme Frage stellen muss]).

    Nun, in diesem Thread wurden mir bessere Implementierungen für die is_printable<> -Klasse vorgeschlagen, die ich dann so sehr ich konnte umgeändert und dann verwendet habe (Danke nochmals an einself und camper). Meine is_printable<> -Implementation sieht wie folgt aus:

    template<typename Type, typename = std::ostream&>
    class is_printable : public std::false_type {};
    
    template<typename Type>
    class is_printable<Type, decltype(std::declval<std::ostream&>() << std::declval<Type>())> : public std::true_type {};
    

    Jedoch scheint der Compiler nicht damit klarzukommen, wenn ich die Klasse wie folgt in meiner Title-Klasse (im Konstruktor) verwende:

    template<typename TitleType, typename LineType = std::string,
              typename = typename std::enable_if<is_printable<TitleType>::value && is_printable<LineType>::value>::type>
    title(const TitleType& title_name, const LineType& title_line = LineType())
        : ... {}
    

    Wenn ich jedoch folgendes mache...

    template<typename TitleType, typename LineType = std::string,
              typename = typename std::enable_if<true /*is_printable<TitleType>::value && is_printable<LineType>::value*/>::type>
    title(const TitleType& title_name, const LineType& title_line = LineType())
        : ... {}
    

    ...kommt der G++ damit klar.

    Um mir auch ganz sicher zu sein, dass der interne Compiler-Bug auch wirklich davon entsteht, habe ich diesen Prozess oftmals wiederholt, d.h. ich habe rund 10 - 20 Mal is_printable<TitleType>::value && is_printable<LineType>::value auskommentiert und durch true ersetzt und jedes Mal als ich das Zeug auskommentiert habe, war nichts mehr vom Compiler-Bug zu sehen. Jedes Mal wo ich die Kommentare wieder entfernt habe, tauchte der Bug wieder auf.

    Was ich komisch finde, ist, dass ich die is_printable<> -Klasse nicht nur in diesem Konstruktor verwende. Beispielsweise hat meine Title-Klasse eine Methode die wie folgt aussieht:

    template<typename Type, typename = typename std::enable_if<is_printable<Type>::value>::type>
    void set_name(const Type& title_name){
        name = nothrow_cast<std::string>(title_name);
    }
    

    Wobei hier kein Compiler-Bug zustande kommt.
    Ich kann sehr schlecht auf meine is_printable<> -Klasse verzichten, und möchte, dass das nun doch noch irgendwie damit funktioniert. Irgendwelche Vorschläge?

    Wer noch mehr Informationen braucht, muss einfach Bescheid sagen.
    Grüße.



  • Schritt 1: Aktuelle GCC-Version aus dem VCS auschecken und bauen (wenn du das nicht schon längst machst). Versuchen das Problem zu reproduzieren.

    Schritt 2: Wenn Problem immer noch vorhanden, Bugreport erstellen.



  • Schritt 0: den exakten Quelltext posten.



  • Eigentlich wollte ich dir zeigen, wie du dein typename enable_if<is_printable<A>::value && is_printable<B>::value>::type zu enable_if_printable<A, B> vereinfachen kannst, aber dann hat der Segmentation-fault auch mich heimgesucht.

    #include <type_traits>
    #include <tuple>
    
    template <typename T, typename... U>
    using all_same = std::is_same<std::tuple<T, U...>, std::tuple<U..., T> >;
    template <template<typename>class P, typename... T>
    using enable_if_all = typename std::enable_if<all_same<std::integral_constant<bool, P<T>::value>...>::value>::type;
    template <typename... T>
    using enable_if_printable = enable_if_all<std::is_arithmetic, T...>;
    
    template<typename A, typename B, typename = enable_if_printable<A, B> >
    void f(A,B){}
    
    int main(){f(1,1.1);}
    

    LC_ALL=C g++ -Wall -Wextra -pedantic -std=c++11 mwe.cc -o mwe
    mwe.cc:5:73: internal compiler error: Segmentation fault
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions.
    Preprocessed source stored into /tmp/ccKCPEgY.out file, please attach this to your bugreport.

    Leider ist LWS gerade down, deshalb kann ich das nicht auf anderen GCCs testen. Mit clang gehts.



  • gcc hat noch ein Paar bekannte Probleme, im Zusammenhang mit variablen Templates und using.
    gcc 4.8. produziert hier normale Fehlermeldungen

    test.cpp: In substitution of ‘template<class T, class ... U> using all_same = std::is_same<std::tuple<_El0, _El ...>, std::tuple<U ..., T> > [with T = std::integral_constant<bool, P<T>::value>...; U = {U ...}]’:
    test.cpp:8:16:   required from here
    test.cpp:5:73: error: template argument 2 is invalid
     using all_same = std::is_same<std::tuple<T, U...>, std::tuple<U..., T> >;
                                                                             ^
    test.cpp:8:24: error: template argument 1 is invalid
     P<T>::value>...>::value>::type;
                            ^
    test.cpp:10:29: error: expected type-specifier before ‘enable_if_all’
     using enable_if_printable = enable_if_all<std::is_arithmetic, T...>;
                                 ^
    test.cpp:12:45: error: expected type-specifier before ‘enable_if_printable’
     template<typename A, typename B, typename = enable_if_printable<A, B> >
                                                 ^
    test.cpp:12:45: error: expected ‘>’ before ‘enable_if_printable’
    test.cpp: In function ‘int main()’:
    test.cpp:15:19: error: no matching function for call to ‘f(int, double)’
     int main(){f(1,1.1);}
                       ^
    test.cpp:15:19: note: candidate is:
    test.cpp:13:6: note: template<class A, class B, class> void f(A, B)
     void f(A,B){}
          ^
    test.cpp:13:6: note:   template argument deduction/substitution failed:
    

    Das ist zwar immer noch falsch, aber nicht das gesuchte Problem.



  • camper schrieb:

    Schritt 0: den exakten Quelltext posten.

    Klick

    alterbernd schrieb:

    Schritt 1: Aktuelle GCC-Version aus dem VCS[...]

    Nun... Ich hab noch nie was von der Abkürzung "VCS" gehört, könntest Du vielleicht noch schnell erläutern was das ist?

    einself schrieb:

    Leider ist LWS[...]

    Ich habs echt nicht so mit Abkürzungen 😃



  • Eine Abwandlung bringt bei mir sogar clang (3.2) zum Absturz. Während gcc (4.3.6, 4.4.7, 4.5.4, 4.6.3) ebenfalls mit ICE aussteigen, beschweren sich gcc 4.7.2 und 4.8.0 über Überschreitung der Instantiierungstiefe. Da könnte sogar etwas dran sein.

    template <bool, typename = void> struct enable_if {};
    template <typename T> struct enable_if<true,T> { typedef T type; };
    
    struct A {};
    
    template<typename T, typename = A&>
    struct trait
    { static const bool value = false; };
    
    template<typename T>
    struct trait<T, decltype(fun( (A()), (T()) ))>
    { static const bool value = true; };
    
    struct foo
    {
        foo() {}
        template<typename T>
        foo(const T&, typename enable_if<trait<T>::value>::type* =0)
        {}
    };
    
    A& fun(A, foo);
    A& fun(A, int);
    
    int main()
    {
        int x;
        foo y(x);
    }
    


  • Es scheint, als ob die Instantiierung des Templatekonstruktors (genauer: der Deklaration) eine Copy/Move umfasst - und obwohl nat. die üblichen Copy/Move-Konstruktoren zur Verfügung stehen, führt das zu rekursiver Instantiierung. Denn der Konstruktor ist zwar kein Copy-ctor, aber trtzdem einer, der zum Kopieren eines Objektes geeignet wäre. Wenn ich einen Dummyparamtere hinzufüge

    template <bool, typename = void> struct enable_if {};
    template <typename T> struct enable_if<true,T> { typedef T type; };
    
    struct A {};
    
    template<typename T, typename = A&>
    struct trait
    { static const bool value = false; };
    
    template<typename T>
    struct trait<T, decltype(fun( (A()), (T()) ))>
    { static const bool value = true; };
    
    struct foo
    {
        foo() {}
        template<typename T>
        foo(int, const T&, typename enable_if<trait<T>::value>::type* =0)
        {}
    };
    
    A& fun(A, foo);
    A& fun(A, int);
    
    int main()
    {
        int x;
        foo y(0,x);
    }
    

    gibt es keine Probleme mit irgendeinem der Compiler, die ich getest habe. Das scheint auch mit gnihihihihi s Code zu funktionieren. Schön ist das nat. nicht.



  • Tatsache! 😃
    Mit dem Dummyparameter läufts wie geschmiert, Danke für die Info.

    "Gelöst" habe ich das nun so:

    class title{
    ...
    
        template<typename TitleType, typename LineType,
                  typename = typename std::enable_if<is_printable<TitleType>::value && is_printable<LineType>::value>::type>
        title(char, const TitleType& title_name, const LineType& title_line)
            : name(nothrow_cast<std::string>(title_name)), line(nothrow_cast<std::string>(title_line)) {}
    
    public:
    
    ...
    
        template<typename TitleType, typename LineType = std::string>
        title(const TitleType& title_name, const LineType& title_line = LineType()) : title(0, title_name, title_line) {}
    ...
    };
    


  • Damit wird die Überladung aber nicht mehr ohne Fehler entfernt. Wenn das so sein soll, wäre static_assert mit einer passend Fehlermeldung sinnvoller.



  • camper schrieb:

    Damit wird die Überladung aber nicht mehr ohne Fehler entfernt. Wenn das so sein soll, wäre static_assert mit einer passend Fehlermeldung sinnvoller.

    Uhm...
    Stimmt, ich verstehe aber grad nicht warum.

    Dann benutze ich eben vorerst einen static_assert .



  • Nun, so gehts auch:

    template<typename TitleType, typename LineType = std::string>
                title(const TitleType& title_name, const LineType& title_line = LineType()){
                    set_name(title_name);
                    set_line(title_line);
                }
    

    wegen:

    template<typename Type, typename = typename std::enable_if<is_printable<Type>::value>::type>
                void set_name(const Type& title_name){
                    name = nothrow_cast<std::string>(title_name);
                }
    
                template<typename Type, typename = typename std::enable_if<is_printable<Type>::value>::type>
                void set_line(const Type& title_line){
                    line = nothrow_cast<std::string>(title_line);
                }
    

    Aber der lässt dennoch jeden Typ durch - ob printable oder nicht o__O

    Folgendes kompiliert bei mir einwandfrei:

    int main(){
        class X {} x;
        fast::io::title t(x); // oder fast::io::title().set_name(x);
        return 0;
    }
    

    Sollte es aber nicht.

    Mit static_assert habe ich es auch schon versucht, der lässt ebenfalls jeden Typen durch.

    Das hab ich so benutzt:

    static_assert(is_printable<TitleType>::value && is_printable<LineType>::value, "hier die fehlermeldung");
    

    Was mach ich denn nun schon wieder falsch? o__O
    Und vor allem wo ist der Kopf-Gegen-Die-Wand-Smiley?

    Grüße...


Anmelden zum Antworten