2014-12-19 6 views
6

Betrachten Sie dieses Programm:Kann garantierte UB zur Kompilierungszeit zurückgewiesen werden?

#include <stdio.h> 

int main(void) 
{ 
    int x; 
    while (1 == scanf("%d", &x)) 
     printf("%c\n", "hello"[x]); 
} 

Der Compiler dies erfolgreich kompilieren muss, weil das Programm keine UB hat, solange der Benutzer keine Zahlen außerhalb des Bereichs 0 eintritt - 4.

Jedoch kann UB nach this thread zurück in der Zeit reisen. Jetzt dieses Programm betrachten:

int main(void) 
{ 
    printf("hello\n"); 
    "hello"[6]; 
} 

Jeder Aufruf dieses Programm führt zu undefiniertem Verhalten, und da die-Laufzeit kann das gesamte Verhalten des Programms auf jedem Aufruf ist nicht definiert. Kann der Compiler das Programm daher ablehnen und keine ausführbare Datei erzeugen? (Wir könnten sagen, dass die UB zurück in die Zeit der Kompilierung reist!)

+5

@Zaffy: '" Hallo "[5]' ist '' 0'', '" Hallo "[6]' ist außerhalb des Rahmens. – Jarod42

+0

@ Jarod42 oh, yeah, sorry :) – Zaffy

+2

Zuverlässige und sichere Erkennung von undefiniertem Verhalten ist ein unausführbares oder unentscheidbares Problem .... –

Antwort

13

Kann der Compiler daher das Programm ablehnen und keine ausführbare Datei erzeugen?

Ja. Die Definition von undefiniertem Verhalten ist:

Verhalten, für die diese Internationale Norm keine Anforderungen auferlegt [Anmerkung: undefiniertes Verhalten kann erwartet werden, wenn diese Internationale Norm eine ausdrückliche Definition des Verhaltens läßt oder wenn ein Programm verwendet eine fehlerhaftes konstruieren oder fehlerhafte Daten. Zulässiges undefiniertes Verhalten reicht von der vollständigen Ignorierung der Situation mit unvorhersehbaren Ergebnissen bis hin zum Verhalten bei der Übersetzung oder Programmausführung in dokumentierter Weise für die Umgebung charakteristisch (mit oder ohne Ausgabe einer Diagnosemeldung), zum Beenden einer Übersetzung oder Ausführung (mit die Ausgabe einer Diagnosemeldung). Viele fehlerhafte Programmkonstrukte erzeugen kein undefiniertes Verhalten; Sie müssen diagnostiziert werden. - Endnote]

4

Um Jonathans Antwort hinzuzufügen.

Das zweite Programm ruft undefiniertes Verhalten auf und ein Compiler hat das Recht, die Übersetzung zu stoppen, da undefiniertes Verhalten nicht begrenzt ist (c11, 3.4.3p1).

Das erste Programm kann nicht definiertes Verhalten aufrufen, aber der Compiler kann die Übersetzung nicht stoppen, da nicht alle Ausführungspfade undefiniertes Verhalten erzeugen.

In Defect Report #109, C Ausschuss sagt:

Wenn weiterhin jede mögliche Ausführung eines bestimmten Programms in undefinierten Verhalten führen würde, das gegebene Programm nicht streng Conforming ist. Eine konforme Implementierung muss nicht unbedingt ein streng konformes Programm übersetzen, weil eine mögliche Ausführung dieses Programms zu undefiniertem Verhalten führen würde.

Verwandte Themen