Frage C ++ 0x, Compiler-Hooks und fest codierte Sprachen


Ich bin ein wenig neugierig auf einige der neuen Funktionen von C ++ 0x. Bestimmtes bereichsbasierte for-Schleifen und Initialisierungslisten. Beide Funktionen benötigen eine benutzerdefinierte Klasse, um korrekt zu funktionieren.

Ich kam über mich dieser Beitragund während die Top-Antwort hilfreich war. Ich weiß nicht, ob das völlig richtig ist (Ich bin wahrscheinlich nur völlig falsch verstanden, siehe 3. Kommentar zur ersten Antwort). Entsprechend der aktuelle Spezifikationen Für Initialisierungslisten definiert der Header einen Typ:

template<class E> class initializer_list {
public:
    initializer_list();

    size_t size() const; // number of elements
    const E* begin() const; // first element
    const E* end() const; // one past the last element
};

Sie können dies in den Spezifikationen sehen, nur Strg + F 'Klasseninitialisierungsliste'.

Damit = {1,2,3} implizit in die initializer_list Klasse, der Compiler HAT Kenntnisse über die Beziehung zwischen {} und initializer_list. Es gibt keinen Konstruktor, der irgendetwas empfängt, also ist die initializer_list, soweit ich das beurteilen kann, ein Wrapper, der an alles gebunden wird, was der Compiler tatsächlich erzeugt.

Es ist das gleiche mit dem for( : ) Schleife, die auch einen benutzerdefinierten Typ benötigt, um zu arbeiten (obwohl gemäß den Spezifikationen aktualisiert, um keinen Code für Arrays und Initialisierungslisten zu erfordern. Aber Initialisierungslisten erfordern <initializer_list>, so ist es eine benutzerdefinierte Code-Anforderung durch Proxy).

Verstehe ich komplett falsch, wie das hier funktioniert? Ich bin nicht falsch bei der Annahme, dass diese neuen Funktionen tatsächlich extrem stark auf den Benutzercode angewiesen sind. Es fühlt sich an, als ob die Features halb gebacken sind, und anstatt das gesamte Feature in den Compiler zu integrieren, wird es vom Compiler zur Hälfte gemacht und zur Hälfte in includes. Was ist der Grund dafür?

Bearbeiten: Ich tippte 'stark auf Compiler-Code' und nicht 'stark auf Benutzer-Code'. Was ich denke, warf meine Frage völlig ab. Meine Verwirrung besteht nicht darin, dass neue Features in den Compiler eingebaut werden, sondern in den Compiler, der auf Benutzercode basiert.


5
2017-12-07 02:35


Ursprung


Antworten:


Ich bin nicht falsch in der Annahme, dass diese neuen Funktionen tatsächlich extrem stark auf Compiler-Code angewiesen sind

Sie sind extrem auf den Compiler angewiesen. Ob Sie eine Kopfzeile hinzufügen müssen oder nicht, Tatsache ist, dass in beiden Fällen die Syntax bei heutigen Compilern ein Parsing-Fehler wäre. Das for (:) passt nicht ganz in den heutigen Standard, wo das einzige erlaubte Konstrukt ist for(;;)

Es fühlt sich an, als ob die Features halb gebacken sind, und anstatt das gesamte Feature in den Compiler zu integrieren, wird es vom Compiler zur Hälfte gemacht und zur Hälfte in includes. Was ist der Grund dafür?

Die Unterstützung muss im Compiler implementiert sein, aber Sie müssen einen System-Header einfügen, damit er funktioniert. Dies kann verschiedenen Zwecken dienen, im Falle von Initialisierungslisten bringt es den Typ (Schnittstelle zur Compiler-Unterstützung) in den Bereich für den Benutzer, so dass Sie eine Möglichkeit haben, es zu benutzen (denken Sie daran, wie va_args in C sind). Im Fall der bereichsbasierten für (die nur syntaktischer Zucker ist) müssen Sie Range in den Geltungsbereich bringen, damit der Compiler seine Magie ausführen kann. Beachten Sie, dass der Standard definiert for ( for-range-declaration : expression ) statemententspricht ([6.5.4] / 1 im Entwurf):

{ 
   auto && __range = ( expression ); 
   for ( auto __begin = std::Range<_RangeT>::begin(__range), 
         __end = std::Range<_RangeT>::end(__range); 
         __begin != __end; 
         ++__begin ) { 
      for-range-declaration = *__begin; 
      statement 
   } 
} 

Wenn Sie es nur für Arrays und STL-Container verwenden möchten, die ohne das implementiert werden könnten Range Konzept (nicht im Sinne von C ++ 0x), aber wenn Sie die Syntax in benutzerdefinierte Klassen (eigene Container) erweitern möchten, kann der Compiler leicht von den vorhandenen abhängen Range Vorlage (mit Ihrer eigenen möglichen Spezialisierung). Der Mechanismus, der von einer definierten Vorlage abhängt, entspricht dem Erfordernis einer statischen Schnittstelle auf dem Container.

Die meisten anderen Sprachen sind in die Richtung gegangen, eine reguläre Schnittstelle zu benötigen (zB Container, ...) und verwenden dafür Laufzeit-Polymorphismus. Wenn dies in C ++ getan werden müsste, müsste die gesamte STL ein größeres Refactoring durchlaufen, da STL-Container keine gemeinsame Basis oder Schnittstelle haben und nicht bereit sind, polymorph verwendet zu werden.

Falls vorhanden, wird der aktuelle Standard nicht sein unterbacken bis es ausgeht.


3
2017-12-07 07:46



Es ist nur Syntaxzucker. Der Compiler erweitert die angegebenen syntaktischen Konstrukte in äquivalente C ++ - Ausdrücke, die direkt auf die Standardtypen / Symbolnamen verweisen.

Dies ist nicht die einzige starke Kopplung, die moderne C ++ - Compiler zwischen ihrer Sprache und der "Außenwelt" haben. Beispielsweise, extern "C" ist ein bisschen ein Sprach-Hack, um das Verknüpfungsmodell von C aufzunehmen. Sprachorientierte Deklarationen thread-lokaler Speicher hängen implizit davon ab, dass viele RTL-Hacker funktionieren.

Oder sehen Sie sich C an. Wie können Sie auf Argumente zugreifen, die über übergeben wurden? ...? Sie müssen sich auf die Standardbibliothek verlassen. aber das verwendet Magie, die eine sehr harte Abhängigkeit davon hat, wie genau der C-Compiler Stack-Frames auslegt.

AKTUALISIEREN:

Wenn überhaupt, ist der Ansatz, den C ++ hier gewählt hat, mehr im Geiste von C ++ als die Alternative - was wäre, ein hinzuzufügen intrinsisch Sammlung oder Bereichstyp, in der Sprache gebacken. Stattdessen wird dies über einen vom Anbieter definierten Bereichstyp ausgeführt. Ich sehe es nicht so sehr anders als variadische Argumente, die ohne die herstellerdefinierten Accessor-Makros ähnlich nutzlos sind.


1
2017-12-07 03:32