Stai compilando con l'opzione -std=c99
.
Questo disabilita alcune estensioni GCC non standard come asm
caratteristica.
Vedi https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 per della documentazione (non molto precisa).
Rimuovi o modifica la riga set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
dal tuo cmakefile se hai bisogno di assembly inline.
Usa __asm__
invece di asm
con -std=c99
o usa -std=gnu99
Dai documenti GCC https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html
La parola chiave asm è un'estensione GNU. Quando scrivi codice che può essere compilato con -ansi e le varie opzioni -std, usa
__asm__
invece di asm (vedi Parole chiave alternative).
e https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords:
-ansi e le varie opzioni -std disabilitano determinate parole chiave. Ciò causa problemi quando si desidera utilizzare estensioni GNU C o un file di intestazione generico che dovrebbe essere utilizzabile da tutti i programmi, inclusi i programmi ISO C. Le parole chiave asm, typeof e inline non sono disponibili nei programmi compilati con -ansi o -std (sebbene inline possa essere usata in un programma compilato con -std=c99 o -std=c11). La parola chiave ISO C99 limit è disponibile solo quando viene utilizzata -std=gnu99 (che alla fine sarà l'impostazione predefinita) o -std=c99 (o l'equivalente -std=iso9899:1999), o un'opzione per una versione standard successiva.
Il modo per risolvere questi problemi è inserire
__
all'inizio e alla fine di ogni parola chiave problematica. Ad esempio, utilizza__asm__
invece di asm, e__inline__
anziché in linea.Altri compilatori C non accetteranno queste parole chiave alternative; se vuoi compilare con un altro compilatore, puoi definire le parole chiave alternative come macro per sostituirle con le parole chiave abituali. Assomiglia a questo:
#ifndef __GNUC__ #define __asm__ asm #endif
-pedantic e altre opzioni causano avvisi per molte estensioni GNU C. Puoi impedire tali avvisi all'interno di un'espressione scrivendo
__extension__
prima dell'espressione.__extension__
non ha alcun effetto a parte questo.
-std=gnu99
abilita le estensioni GNU come asm
, pur mantenendo il linguaggio simile a C99.
Standard C99
GCC funziona in questo modo per conformarsi allo standard C99, che contrassegna i simboli di doppia sottolineatura come riservati.
Dalla bozza standard C99 N1256 7.1.3 "Identificativi riservati" 1:
Ogni intestazione dichiara o definisce tutti gli identificatori elencati nella sottoclausola associata e, facoltativamente, dichiara o definisce gli identificatori elencati nella sottoclausola e gli identificatori relativi alle indicazioni future della libreria che sono sempre riservati per qualsiasi uso o per l'uso come identificatori di ambito di file.
- Tutti gli identificatori che iniziano con un trattino basso e una lettera maiuscola o un altro trattino basso sono sempre riservati per qualsiasi uso.
Altrimenti, se asm
erano predefiniti, un programma legale come:
int asm = 0;
diventerebbe illegale.
Programma di prova
#include <assert.h>
#include <stdint.h>
int main(void) {
uint32_t io = 0;
__asm__ volatile (
"movl %0, %%eax;"
"inc %%eax;"
"movl %%eax, %0;"
: "+m" (io)
:
: "%eax"
);
assert(io == 1);
}
Testato su Ubuntu 17.10, GCC 7.2.
asm
è un'estensione gcc, quindi non puoi usarla con flag come std=c99
o ansi
Maggiori dettagli su https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions