Variadischer Konstruktor



  • Hallo,

    mein VS 2013 Express Compiler stürzt bei folgendem Code ab:

    #include <iostream>
    
    struct Loud
    {
    	Loud(...)
    	{
    		std::cout << '+';
    	}
    	Loud(Loud const&)
    	{
    		std::cout << '+';
    	}
    	~Loud()
    	{
    		std::cout << '-';
    	}
    };
    
    int main()
    {
    	Loud Foo[4];
    }
    

    Der Code ist schon korrekt, oder?
    Es wird mir ausgegeben: "Microsoft (R) C/C++-Optimierungscompiler funktioniert nicht mehr"
    Die Problemdetails:

    Problemsignatur:
      Problemereignisname:	APPCRASH
      Anwendungsname:	CL.exe
      Anwendungsversion:	18.0.21005.1
      Anwendungszeitstempel:	524faabf
      Fehlermodulname:	c1xx.dll
      Fehlermodulversion:	18.0.21005.1
      Fehlermodulzeitstempel:	524faa90
      Ausnahmecode:	c0000005
      Ausnahmeoffset:	0009e05e
      Betriebsystemversion:	6.1.7601.2.1.0.256.48
      Gebietsschema-ID:	2055
    

    In der IDE wird mir folgendes ausgegeben:

    fatal error C1001: Interner Compilerfehler.
    1>  (Compilerdatei 'msc1.cpp', Zeile 1325)
    

    Wenn der Code korrekt ist, ist der Bug bekannt?

    Gruss

    Edit:
    Bei einer typsicheren variadischen Argumentenliste tritt dasselbe Problem auf (der Compiler stürzt auch ab):

    template<typename... T>
    	Loud(T...)
    	{
    		std::cout << '+';
    	}
    

    Edit 2: #include vergessen und daher nachgetragen.



  • Lol oO, in der Tat (ich hab hier nicht die Express Version, sondern Professional mit dem Update 3)



  • gcc gibt aus: ++++----



  • Ohne den variadischen Konstruktor, d.h. nur mit Standardkonstruktor, kommt sowas raus wie +----



  • Skym0sh0 schrieb:

    Ohne den variadischen Konstruktor, d.h. nur mit Standardkonstruktor, kommt sowas raus wie +----

    Du hast im Standardkonstruktor aber schon die Ausgabe vom Plus-Zeichen drin, oder? Denn ich kann genanntes Verhalten nicht reproduzieren, weder mit noch ohne Optimierungen.



  • Wie werden denn Arrays initialisiert? Alle default initialisiert, oder ein "Parameter" default initialisiert und die anderen dann von diesem kopiert (ala vector ctor)?



  • hustbaer schrieb:

    Wie werden denn Arrays initialisiert? Alle default initialisiert, oder ein "Parameter" default initialisiert und die anderen dann von diesem kopiert (ala vector ctor)?

    §8.5/6 schrieb:

    To default-initialize an object of type T means:
    [...]
    — if T is an array type, each element is default-initialized;

    Ich geh jetzt einfach mal davon aus, dass das eine default-Initialization ist, zu faul im Standard danach zu suchen.

    Edit: Oh, hier:

    §8.5/11 schrieb:

    If no initializer is specified for an object, the object is default-initialized;

    Also, ja da sollte vier mal '+' kommen.


  • Mod

    Wie werden denn Arrays initialisiert?

    😮



  • hustbaer schrieb:

    Wie werden denn Arrays initialisiert? Alle default initialisiert, oder ein "Parameter" default initialisiert und die anderen dann von diesem kopiert (ala vector ctor)?

    Alle in aufsteigender Reihenfolge default initialized und Destruktor dann natürlich genau umgekehrt.

    Ist wohl in der Tat ein Bug, hast du ihn schon reported? Mit Initializer geht's bei mir:

    Loud Foo[] = { {}, {}, {}, {} };
    

  • Mod

    hustbaer schrieb:

    Wie werden denn Arrays initialisiert? Alle default initialisiert, oder ein "Parameter" default initialisiert und die anderen dann von diesem kopiert (ala vector ctor)?

    Interessant wird diese Frage, wenn der Defaultkonstruktor selbst ein Defaultargument hat.

    struct foo {};
    struct bar { bar(foo=foo()) {} };
    bar* p = new bar[1000000];
    

    Hier gilt eine Ausnahme, was die Lebenszeit des Defaultargumentes betrifft: es lebt nicht bis zum Ende des Ausdruckes (Stackoverflow lässt grüßen), sondern nur jeweils bis zum Ende der Initialierung des Elementes, zu dem es gehört.



  • Wieso 😮?

    Ich war mir eh so-gut-wie sicher dass jedes Element einzeln default-initialized wird. Die andere Variante hätte aber zu dem von Skym0sh0 beschriebenen Verhalten gepasst. OK, nicht ganz, da es dann ein "-" zu wenig wäre.

    OK, wenn ich ein wenig länger darüber nachdenke... weiss ich es eigentlich. Indirekt. Weil ich weiss dass man Arrays von nicht kopierbaren Typen machen kann. Was ja nicht gehen kann wenn es ala vector gemacht würde.

    Andrerseits... danke für das Kompliment 🙂



  • asfdlol schrieb:

    Skym0sh0 schrieb:

    Ohne den variadischen Konstruktor, d.h. nur mit Standardkonstruktor, kommt sowas raus wie +----

    Du hast im Standardkonstruktor aber schon die Ausgabe vom Plus-Zeichen drin, oder? Denn ich kann genanntes Verhalten nicht reproduzieren, weder mit noch ohne Optimierungen.

    Mh, jetzt wo dus sagst.

    Ich hatte vorhin etwas rumprobiert und zwischendurch kam mal die Ausgabe: "+----", aber wenn ich jetzt so drüber nachdenke und auch den Test wiederhole ist alles wie erwartet. Keine Ahnung mehr wie ich diese Ausgabe hinbekommen hab.

    Wahrscheinlich mal wieder Tomaten auf den Augen (Ó_Ó) unso



  • @camper
    Cool, danke für die Info. Wusste ich auch nicht.

    Wieder so eine Spezialregel die zwar wirklich Sinn macht, die Sprache dafür aber auch um ein kleines Stück komplizierter macht.


  • Mod

    hustbaer schrieb:

    Andrerseits... danke für das Kompliment 🙂

    Joa. Ich weiß doch wie kompetent du bist, hat mich halt ein wenig erschreckt 🙂


Anmelden zum Antworten