2014-02-24 1 views
13

Im Standard C (C99/C11) haben wir die Integer-Konstantenausdrücke, die konstante Ausdrücke sind, deren Operanden alle konstante ganze Zahlen sind .Operatoren verboten (oder nicht?) Bei der Definition ganzzahliger konstanter Ausdrücke (in C)

Die folgende Definition gilt:

Standard-C99, Abschnitt 6.6 (par.6):

eine ganzzahlige Konstante Ausdruck) soll Integer-Typ haben, und wird nur Operanden haben, die ganze Zahl sind, costants, Enumerationskonstanten, Zeichenkonstanten, sizeof-Ausdrücke, deren Ergebnisse ganzzahlige Konstanten sind, und Gleitkommakonstanten, die die unmittelbaren Operanden von sind.

Standard C99

Dies scheint nach der Definition des allgemeineren konstanten Ausdruck.
(Da ganzzahlige Konstante Ausdruck nach konstantem Ausdruck definiert ist gehe ich davon aus, daß die erstere ein besonderer Fall der letzten ist.)

Auf der anderen Seite, Bedingungsausdrückekonstanten Ausdrücke betrachtet werden durch die folgende Regel eingeschränkt:

Standard-C99, Abschnitt 6.6:

Konstante Ausdrücke dürfen keine Zuweisungen, Inkremente, Dekrement-, Funktionsaufruf- oder Kommaoperatoren enthalten, außer wenn sie innerhalb eines Teilausdrucks enthalten, der nicht ausgewertet wird.

Durch die Bedeutung von bedingtem Ausdruck Abrollen uns zum postfix Ausdrücke fallen können und/oder einstelligen Ausdrücke. Wenn wir diese Bedingungen auf ganzzahlige Konstantenausdrücke anwenden, erhalten wir grob, dass sie aus Bedingungsausdrücken bestehen, die so eingeschränkt sind, dass jeder Operand ganzzahlige/enumeration/character -Konstanten (oder floating constant unmittelbar vor a cast), und so dass gibt es keine Zuweisung, Inkrement, Dekrement, Funktionsaufruf oder Komma-Operatoren.

  • Durch Einfachheit halber nehmen wir an, dass E ein solcher Ausdruck ist, ohne sizeof Betreiber und ohne nicht bewerteter Operanden.

meine Frage:
Sind die folgenden Operatoren indirekt in E verboten:

  • & (Adresse),
  • * (Indirektion),
  • [] (array -subskript),
  • . (Strukturelement),
  • -> (Zeiger auf Strukturelemente).

Darüber hinaus sind zusammengesetzte Literale auch verboten?

Zusätzliche Anmerkung: Ich bin an der Beantwortung dieser Frage für streng konforme Programme (C99/C11) interessiert.

Ich denke, dass sie in keinem Unterausdruck von E sein können, aber ich bin mir nicht sicher, ob das völlig stimmt. Meine Schnell Argumentation ist wie folgt:

  • Wenn F eine ganzzahlige Konstante subexpression von E ist, dann F hat per Definition einen ganzzahligen Typ T.
  • Wenn der unären Operator & erscheint vor F in E, dann & F einen Operanden mit Typ "Zeiger auf T" in, die nicht in E erlaubt ist (in trotz dass F ist kein Objekt, sondern nur ein ganzzahliger Wert, daher kann & nicht angewendet werden). Somit kann & in keinem E erscheinen.
  • Seit F hat keinen Zeigertyp, es hat keinen Sinn den Ausdruck *F.
  • Ein Index-Operator [] wird verwendet, um ein Element innerhalb eines Arrays anzugeben. Dies bedeutet, dass wir in E so etwas wie A[N] haben. Hier muss N ein ganzzahliger konstanter Ausdruck sein. Wir bemerken jedoch, dass A auch ein Operand ist, aber es ist ein Objekt vom Typ array, das in E nicht erlaubt ist. Dies bedeutet, dass der Array-Subscript-Operator nicht in E erscheinen kann.
  • Wenn wir in E die Betreiber . und -> haben, es bedeutet, sie in E verwendet werden wie folgt: S.memb pS->memb. Somit haben wir den Operanden S, dessen Typ struct oder union und pS ist, was ein pointer to struct or pointer to union ist. Aber diese Art von "Operanden" ist in E nicht erlaubt.
  • Zusammengesetzte Literale sind in E nicht erlaubt, weil sie lvalues ​​sind, was bedeutet, dass sie eine Adresse haben, wenn das Programm läuft. Da eine solche Adresse vom Compiler nicht erkannt werden kann, wird der Ausdruck, der ein zusammengesetztes Literal enthält, nicht als Konstante betrachtet.

Denken Sie, dass meine Überlegungen richtig sind?
Kennen Sie Ausnahmefälle, in denen einige dieser Operatoren oder Ausdrücke [Teil von] Integer-Konstanten Ausdruck sein können (wie in dem eingeschränkten Fall, dass ich E bezeichnet).

+0

Sie _are_ scherzen, richtig? Hast du übrigens mein Kalkülbuch geschrieben? – ryyker

+4

@ryyker: Ich weiß nicht, was du meinst. Du kannst auf meine Fehler hinweisen, wenn du willst. – pablo1977

+0

Mein Kommentar ist ein wenig ironisch, ich deute darauf hin, dass dies eine zusammengesetzte und komplizierte Reihe von Fragen ist. Aber jemand muss es übernehmen. – ryyker

Antwort

2

Ein ICE muss nur Werte (rvalues ​​im Jargon) als primäre Ausdrücke haben, aus denen er besteht, und keine Objekte (lvalues).

Wenn Sie von dort aufbauen auszuschließen Operatoren, die Sie sehen, dass

  • keiner der Betreiber, die einen L-Wert als Operand müssen verwendet werden können (Zuordnung, Erhöhung, Senkung einstellige &)

  • keine der Operatoren, die einen L-Wert erzeugen kann, entweder (unären *, array Mitglied [], Mitglied ->)

  • verwendet werden, die . Operatoren, die ein struct als Argument benötigt, da

    • gibt es keine Literale für struct

    • Verbindung Literale eine falsche Bezeichnung sind, sie sind Objekte.

    • Funktionsaufrufe sind ebenfalls nicht erlaubt.

Einige dieser Betreiber an Orten erscheinen können, wenn sie nicht bewertet werden (oder nicht nicht sein soll), insbesondere _Alignof, das Makro offsetof und einige Auftritte von sizeof.

+1

Warum haben Sie keine Liste der zweiten Ebene eingefügt, indem Sie vier Leerzeichen vorangestellt haben? – dyp

+0

+1 Gute Antwort. – Caleb

+0

Nicht ganz so glücklich. Der Standard definiert ICE nicht in Form von "Werten", da der Wert "genaue Bedeutung des Inhalts eines Objekts ist, wenn er als ein bestimmter Typ interpretiert wird". Außerdem kann eine Implementierung andere Formen von konstanten Ausdrücken akzeptieren. Zum Beispiel könnte "abc" [1] 'durchaus als Zeichenkonstante akzeptiert werden. –