2016-04-06 11 views
6

Meine Frage sollte heute nicht sehr kompliziert sein, aber ich kann einfach keinen Grund/Lösung finden. Als kleines, reproduzierbares Beispiel des folgenden Spielzeug-C-Code betrachtenC Vorverarbeitung stoppt nicht sofort nach einem # Fehler

#define _state_ 0 

#if _state_ == 1 
int foo(void) {return 1;} 
#else 

/* check GCC flags first 
    note that -mfma will automatically turn on -mavx, as shown by [gcc -mfma -dM -E - < /dev/null | egrep "SSE|AVX|FMA"] 
    so it is sufficient to check for -mfma only */ 

#ifndef __FMA__ 
#error "Please turn on GCC flag: -mfma" 
#endif 

#include <immintrin.h> /* All OK, compile C code */ 
void foo (double *A, double *B) { 
    __m256d A1_vec = _mm256_load_pd(A); 
    __m256d B_vec = _mm256_broadcast_sd(B); 
    __m256d C1_vec = A1_vec * B_vec; 
    } 
#endif 

ich von

gcc -fpic -O2 -c test.c 

Hinweis Diese test.c Datei kompilieren werde ich nicht auf GCC Flagge drehe mich -mfma, so dass die #error werden ausgelöst werden. Was ich erwarten würde, ist, dass Kompilierung wird sofort zu stoppen, nachdem GCC diese #error sieht, aber das ist, was ich mit GCC bekam 5,3:

test.c:14:2: error: #error "Please turn on GCC flag: -mfma" 
#error "Please turn on GCC flag: -mfma" 
^
test.c: In function ‘foo’: 
test.c:22:11: warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi] 
    __m256d A1_vec = _mm256_load_pd(A); 
     ^

GCC tut stoppt, aber warum ist es auch abholen eine Linie nach #error? Irgendeine Erklärung? Vielen Dank.


Für Leute, die es versuchen möchten, gibt es einige Hardware-Anforderungen. Sie benötigen einen x86-64 mit AVXundFMA Befehlssätzen.

+0

Ältere Versionen von gcc sicherlich verwendet, um Kompilierung auf '# Fehler' abzubrechen, so ist es unklar, ob dies eine Funktion oder eine Regression ist –

+0

Ich sage, dass IDK, ob die gcc-Devs dies aus irgendeinem Grund, oder wenn Es ist ein Compiler-Fehler –

+1

Es wird allgemein als nützlicher für einen Compiler angesehen, ** alle ** Fehler zu melden, nicht nur den ersten, damit Sie alle Probleme beheben können, bevor Sie erneut kompilieren. – Barmar

Antwort

5

Ich habe einen Entwurf Kopie der C ISO-Spezifikation und in § 4/4 - es heißt

Die Umsetzung wird nicht erfolgreich eine Vorverarbeitung Übersetzungseinheit eine #error Präprozessordirektive übersetzen enthält, es sei denn, es ist Teil einer Gruppe, die durch bedingte Inklusion übersprungen wird.

Später, in § 6.10.5, wo #error formal definiert ist, sagt es

Eine Präprozessordirektive des Formulars # error pp-tokens opt new-line die Umsetzung führt zu einer Diagnosemeldung zu erzeugen, die die angegebenen enthalten Sequenz von Vorverarbeitungstoken.

Mit anderen Worten erfordert die Spezifikation nur, dass jeder Code, der ein #error hat nur scheitern muss kompilieren und eine Fehlermeldung auf dem Weg zu berichten, nicht, dass die Zusammenstellung muss sofort so schnell beenden, wie #error erreicht ist .

Angesichts der Tatsache, dass es als gute Praxis gilt, immer die Top-Level-Fehler von einem Compiler vor späteren zu überprüfen, würde ich mir vorstellen, ein kompetenter Programmierer, der eine Reihe von Fehlern beginnend mit einer #error Direktive würde wahrscheinlich wissen, was los war auf.

+2

Dies ist eine Qualität der Implementierung Problem ... es wäre auch konform, wenn der Compiler reagiert auf einen Fehler mit der Nachricht "ha ha Ihr Programm ist schlecht" –

+1

@MM Ich könnte mir einen vernünftigen Compiler-Autor wählen, um die Kompilierung zu melden alle anderen Fehler, die auftreten, wenn es andere Probleme mit der Quelldatei gibt, obwohl Sie Recht haben, dass es wahrscheinlich nicht der beste Anruf ist. – templatetypedef