2016-04-06 12 views
6

Moje pytanie dzisiaj nie powinno być zbyt skomplikowane, ale po prostu nie mogę znaleźć przyczyny/rozwiązania. Jako małe, powtarzalny przykład rozważmy następujący zabawka kod CProces wstępny C nie zatrzymuje się natychmiast po #error

#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 

zamierzam skompilować ten plik test.c przez

gcc -fpic -O2 -c test.c 

Uwaga Nie włącza się flaga GCC -mfma, więc #error będzie być wyzwalane. Co by się spodziewać, że kompilacja będzie natychmiast zatrzymać po GCC widzi ten #error, ale to, co mam z GCC 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 robi przystanki, ale dlaczego to również podnieść linię po #error? Jakieś wyjaśnienie? Dzięki.


Dla osób, które chcą spróbować, istnieje pewne wymaganie sprzętowe. Potrzebne są zestawy instrukcji x86-64 z AVXiFMA.

+0

Starsze wersje gcc na pewno przerwały kompilację na '# error', więc nie jest jasne, czy jest to funkcja, czy regresja. –

+0

Mówię, że IDK czy deweloperzy gcc zrobili to celowo z jakiegoś powodu, czy też jest to błąd kompilatora –

+1

Powszechnie uważa się, że bardziej przydatne dla kompilatora jest zgłaszanie ** wszystkich ** błędów, a nie tylko pierwszego, dzięki czemu można naprawić wszystkie problemy przed ponowną kompilacją. – Barmar

Odpowiedz

5

Mam projekt kopię spec C ISO, aw § 4/4 - stwierdza

Wdrożenie nie będzie skutecznie tłumaczyć jednostkę przenoszącą przerób zawierający dyrektywę #error przebiegu wyprzedzającego, chyba że jest to część grupy pomijanej przy warunkowym włączeniu.

Później, w § 6.10.5, gdzie #error jest formalnie zdefiniowany, to mówi

Dyrektywa przerób formularza # error pp-tokens opt new-line powoduje wdrożenie do produkcji komunikat diagnostyczny, który zawiera określony kolejność tokenów przetwarzania wstępnego.

Innymi słowy, spec wymaga jedynie, że każdy kod, który ma #error prostu musi zawieść do kompilowania i zgłosić się komunikat o błędzie po drodze, a nie, że kompilacja natychmiast musi zakończyć jak najszybciej #error osiągnięciu .

Biorąc pod uwagę, że dobrą praktyką jest zawsze sprawdzanie błędów najwyższego poziomu zgłaszanych przez kompilator przed późniejszymi, wyobrażam sobie, że kompetentny programista, który widział ciąg błędów zaczynający się od dyrektywy #error, prawdopodobnie wiedziałby, co się dzieje. na.

+2

To jest problem z jakością implementacji ... byłby również zgodny, gdyby kompilator odpowiedział na jakikolwiek błąd z komunikatem "ha ha Twój program jest zły" –

+1

@MM Mogę wyobrazić sobie rozsądnego autora kompilatora, który zdecyduje się kontynuować kompilację do raportu wszelkie inne błędy napotkane w przypadku innych problemów z plikiem źródłowym, ale masz rację, że prawdopodobnie nie jest to najlepsze połączenie. – templatetypedef

Powiązane problemy