Ist ein Goto im Funktionsumfang von alloca gültig?

8

Der C-Standard verbietet einen Sprung in einen Funktionsumfang, in dem ein VLA existiert.

Ein VLA und der Aufruf der alloca-Funktion sollten dasselbe Ergebnis auf niedriger Ebene haben.

(Ich könnte mich irren, da ich nur ein C bin, kein Low-Level-Programmierer, aber in meiner Vorstellung scheint das witzig zu sein)

Also wird das folgende Snippet auch undefiniert sein?

%Vor%

Natürlich kann ich nicht p referenzieren, aber was ist mit dem Verhalten?

    
dhein 23.05.2014, 07:22
quelle

3 Antworten

4

Tatsächlich besagt die Regel 6.8.6.1:

%Vor%

In Ihrem Code existiert kein Objekt mit variabel modifizierten Typen. alloca macht nicht ein Objekt deklarieren (das muss der Compiler beachten). Somit gibt es keinen Bereich für alloca und keinen Grund für undefiniertes Verhalten im Sinne von Regel 6.8.6.1.

BEARBEITEN

Um die Antwort ein wenig auszuarbeiten: Die "Unbestimmtheit" des Verhaltens im Falle von VLA ist auf das Versprechen einer Deklaration zurückzuführen, dass ein Objekt innerhalb seines Geltungsbereichs (auf Sprachenebene) "bekannt" ist. Im Allgemeinen legt eine Deklaration einen Kontext für die Codeausführung fest. Es ist nicht notwendig, dass es zur Laufzeit ausgeführt wird. Dies gilt jedoch nicht im Fall von VLA: Hier wird dieses Versprechen teilweise zur Laufzeit implementiert, wodurch der statische Deklarationsansatz von C gebrochen wird. Um weitere Konflikte zu vermeiden, die zu einem dynamischen Typisierungssystem führen würden, vermeidet Regel 6.8.6.1 solche Konflikte.

Im Gegensatz dazu ist alloca auf Sprachenebene einfach eine Funktion; sein Aufruf ist kein Anwendungsbereich. Es macht nur ein Versprechen über sein Laufzeitverhalten, falls es aufgerufen wird. Wenn es nicht aufgerufen wird, "erwarten" wir nichts von einer Funktion. Seine reine Existenz wirft also keinen Konflikt auf: Beide Fälle (umgehen oder nicht umgehen) haben eine wohldefinierte Semantik.

    
Matthias 23.05.2014, 08:16
quelle
1
  

Ein VLA und der Aufruf der alloca-Funktion sollten dasselbe Ergebnis auf niedriger Ebene haben.

Es gibt noch ein paar Unterschiede. Ein VLA-Objekt wird verworfen, wenn der Gültigkeitsbereich, für den es deklariert ist, endet und das von alloca zugewiesene Speicherobjekt verworfen wird, wenn die Funktion zurückgibt.

Dies macht einen Unterschied, weil die Anforderung in c99, 6.8.6.1p1 ( "Eine goto-Anweisung nicht außerhalb des Bereichs eines Bezeichners mit einem variabel modifizierten Typ in den Bereich dieses Bezeichners springen darf" ) ist betroffen von der Laufzeitzuordnung / Freigabe von Objekten mit variabel geändertem Typ. Hier wird die alloca -Anweisung nicht ausgeführt, nachdem goto ausgeführt wurde, daher würde ich nicht denken, dass der goto -Aufruf undefiniertes Verhalten aufrufen würde.

    
ouah 23.05.2014 08:29
quelle
1

Der C-Standard sagt nichts über das Verhalten von alloca() aus. Einige Compiler verwenden den Stapel in einer sehr vorhersagbaren Weise und greifen unter Verwendung eines weitgehend redundanten Rahmenzeigers auf automatische Variablen zu. Bei solchen Compilern ist es möglich, Speicherplatz auf dem Stapel zu reservieren, indem einfach ein Wert vom Stapelzeiger subtrahiert wird, ohne dass der Compiler die betreffende Reservierung kennen oder sich darum kümmern muss. Ein solcher Code wird jedoch stark beschädigt, wenn der Compiler den Stack auf eine Weise verwendet, die die Anwendung nicht erwartet hat.

Ich glaube nicht, dass etwas wie:

%Vor%

ist wahrscheinlich gefährlicher als:

%Vor%

Wenn vom Funktionsaufruf zu dem Zeitpunkt, zu dem die alloca() ausgeführt wird, keine Rückstände auf dem Stapel vorhanden sind, wäre jede Operation wahrscheinlich sicher. Wenn zum Zeitpunkt des Allocas Rückstand auf dem Stapel ist (z. B. weil der Compiler die Bereinigung der Argumente von foo bis nach dem Aufruf von bar verzögert), würde sich alloca() schlecht verhalten. Die Verwendung der goto -Version des Codes könnte tatsächlich sicherer sein als die Version mit if , da es für einen Compiler schwieriger ist zu erkennen, dass die Verschiebung der Bereinigung von foo vorteilhaft sein könnte.

    
supercat 19.02.2018 16:01
quelle

Tags und Links