Sie kompilieren mit Option -std=c99
.
Dadurch werden einige nicht standardmäßige GCC-Erweiterungen wie asm
deaktiviert Funktion.
Siehe https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 für einige (nicht sehr genaue) Dokumentation.
Entfernen oder ändern Sie die Zeile set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
aus Ihrer cmakefile, wenn Sie eine Inline-Assemblierung benötigen.
Verwenden Sie entweder __asm__
statt asm
mit -std=c99
, oder verwenden Sie -std=gnu99
Aus den GCC-Dokumenten https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html
Das Schlüsselwort asm ist eine GNU-Erweiterung. Wenn Sie Code schreiben, der mit -ansi und den verschiedenen -std-Optionen kompiliert werden kann, verwenden Sie __asm__
statt asm (siehe Alternative Schlüsselwörter).
und https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords:
-ansi und die verschiedenen -std-Optionen deaktivieren bestimmte Schlüsselwörter. Dies verursacht Probleme, wenn Sie GNU-C-Erweiterungen oder eine Allzweck-Header-Datei verwenden möchten, die von allen Programmen verwendet werden sollte, einschließlich ISO-C-Programmen. Die Schlüsselwörter asm, typeof und inline sind in Programmen, die mit -ansi oder -std kompiliert wurden, nicht verfügbar (obwohl inline in einem Programm verwendet werden kann, das mit -std=c99 oder -std=c11 kompiliert wurde). Das ISO-C99-Schlüsselwort "restrict" ist nur verfügbar, wenn -std=gnu99 (was schließlich der Standard sein wird) oder -std=c99 (oder das Äquivalent -std=iso9899:1999) oder eine Option für eine spätere Standardversion verwendet wird.
Um diese Probleme zu lösen, geben Sie __
ein am Anfang und am Ende jedes problematischen Keywords. Verwenden Sie beispielsweise __asm__
statt asm und __inline__
statt Inline.
Andere C-Compiler akzeptieren diese alternativen Schlüsselwörter nicht; Wenn Sie mit einem anderen Compiler kompilieren möchten, können Sie die alternativen Schlüsselwörter als Makros definieren, um sie durch die üblichen Schlüsselwörter zu ersetzen. Es sieht so aus:
#ifndef __GNUC__
#define __asm__ asm
#endif
-pedantic und andere Optionen verursachen Warnungen für viele GNU-C-Erweiterungen. Sie können solche Warnungen innerhalb eines Ausdrucks verhindern, indem Sie __extension__
schreiben vor dem Ausdruck. __extension__
hat ansonsten keine Wirkung.
-std=gnu99
aktiviert GNU-Erweiterungen wie asm
, wobei die C99-ähnliche Sprache beibehalten wird.
C99-Standard
GCC funktioniert so, um dem C99-Standard zu entsprechen, der doppelte Unterstriche als reserviert markiert.
Aus dem C99 N1256 Standard Draft 7.1.3 "Reserved Identifiers" 1:
Jeder Header deklariert oder definiert alle Identifikatoren, die in seinem zugehörigen Unterabschnitt aufgeführt sind, und deklariert oder definiert optional Identifikatoren, die in seinem zugehörigen Unterabschnitt der zukünftigen Bibliotheksanweisungen aufgeführt sind, und Identifikatoren, die immer entweder für jegliche Verwendung oder für die Verwendung als Dateibereichsidentifizierer reserviert sind.
- Alle Bezeichner, die mit einem Unterstrich und entweder einem Großbuchstaben oder einem anderen Unterstrich beginnen, sind immer für jegliche Verwendung reserviert.
Andernfalls, wenn asm
vordefiniert waren, ein legales Programm wie:
int asm = 0;
illegal werden würde.
Testprogramm
#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);
}
Getestet auf Ubuntu 17.10, GCC 7.2.
asm
ist eine gcc-Erweiterung, daher können Sie nicht mit Flags wie std=c99
verwendet werden oder ansi
Weitere Einzelheiten unter https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions