Kompilujete s volbou -std=c99
.
Tím zakážete některá nestandardní rozšíření GCC, jako je asm
funkce.
Některou (ne příliš přesnou) dokumentaci naleznete na https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112.
Odstraňte nebo změňte řádek set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
z vašeho cmakefile, pokud potřebujete inline montáž.
Buď použijte __asm__
místo asm
s -std=c99
nebo použijte -std=gnu99
Z dokumentů GCC https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html
Klíčové slovo asm je rozšíření GNU. Při psaní kódu, který lze zkompilovat pomocí -ansi a různých voleb -std, použijte
__asm__
místo asm (viz Alternativní klíčová slova).
a https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords:
-ansi a různé volby -std zakazují určitá klíčová slova. To způsobuje potíže, když chcete použít rozšíření GNU C nebo obecný soubor záhlaví, který by měl být použitelný pro všechny programy, včetně programů ISO C. Klíčová slova asm, typeof a inline nejsou dostupná v programech kompilovaných s -ansi nebo -std (ačkoli inline lze použít v programu kompilovaném s -std=c99 nebo -std=c11). Omezení klíčového slova ISO C99 je dostupné pouze tehdy, když je použito -std=gnu99 (které bude nakonec výchozí) nebo -std=c99 (nebo ekvivalentní -std=iso9899:1999), nebo volba pro pozdější standardní verzi.
Způsob, jak vyřešit tyto problémy, je zadat
__
na začátku a na konci každého problematického klíčového slova. Použijte například__asm__
místo asm a__inline__
místo inline.Jiné kompilátory C nebudou tato alternativní klíčová slova akceptovat; pokud chcete kompilovat pomocí jiného kompilátoru, můžete definovat alternativní klíčová slova jako makra a nahradit je obvyklými klíčovými slovy. Vypadá to takto:
#ifndef __GNUC__ #define __asm__ asm #endif
-pedantic a další volby způsobují varování pro mnoho rozšíření GNU C. Takovým varováním v rámci jednoho výrazu můžete zabránit napsáním
__extension__
před výrazem.__extension__
nemá kromě toho žádný účinek.
-std=gnu99
umožňuje rozšíření GNU, jako je asm
, přičemž stále zachovává jazyk podobný C99.
Standard C99
GCC takto funguje v souladu se standardem C99, který označuje symboly dvojitého podtržení jako vyhrazené.
Z návrhu standardu C99 N1256 7.1.3 „Rezervované identifikátory“ 1:
Každá hlavička deklaruje nebo definuje všechny identifikátory uvedené v příslušném podklauzuli a volitelně deklaruje nebo definuje identifikátory uvedené v souvisejícím podklauzuli budoucích směrnic pro knihovny a identifikátory, které jsou vždy vyhrazeny buď pro jakékoli použití, nebo pro použití jako identifikátory rozsahu souborů.
- Všechny identifikátory, které začínají podtržítkem a velkým písmenem nebo jiným podtržítkem, jsou vždy vyhrazeny pro jakékoli použití.
Jinak, pokud asm
byly předdefinovány, legální program jako:
int asm = 0;
stalo by se nezákonným.
Testovací program
#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);
}
Testováno na Ubuntu 17.10, GCC 7.2.
asm
je rozšíření gcc, proto jej nelze použít s příznaky jako std=c99
nebo ansi
Další podrobnosti na https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions