Estás compilando con la opción -std=c99
.
Esto deshabilita algunas extensiones GCC no estándar como asm
característica.
Consulte https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 para obtener documentación (no muy precisa).
Eliminar o cambiar la línea set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
desde su cmakefile si necesita ensamblaje en línea.
Usa __asm__
en lugar de asm
con -std=c99
, o usa -std=gnu99
De los documentos de GCC https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html
La palabra clave asm es una extensión GNU. Al escribir código que se puede compilar con -ansi y las diversas opciones -std, use __asm__
en lugar de asm (ver Palabras clave alternativas).
y https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords:
-ansi y las diversas opciones -std deshabilitan ciertas palabras clave. Esto causa problemas cuando desea usar extensiones GNU C o un archivo de encabezado de uso general que todos los programas deberían poder usar, incluidos los programas ISO C. Las palabras clave asm, typeof e inline no están disponibles en programas compilados con -ansi o -std (aunque inline se puede usar en un programa compilado con -std=c99 o -std=c11). La restricción de palabras clave ISO C99 solo está disponible cuando se usa -std=gnu99 (que eventualmente será el predeterminado) o -std=c99 (o el equivalente -std=iso9899:1999), o una opción para una versión estándar posterior.
La forma de solucionar estos problemas es poner __
al principio y al final de cada palabra clave problemática. Por ejemplo, use __asm__
en lugar de asm, y __inline__
en lugar de en línea.
Otros compiladores de C no aceptarán estas palabras clave alternativas; si desea compilar con otro compilador, puede definir las palabras clave alternativas como macros para reemplazarlas con las palabras clave habituales. Se ve así:
#ifndef __GNUC__
#define __asm__ asm
#endif
-pedante y otras opciones causan advertencias para muchas extensiones GNU C. Puede evitar tales advertencias dentro de una expresión escribiendo __extension__
antes de la expresión. __extension__
no tiene ningún efecto aparte de esto.
-std=gnu99
habilita extensiones GNU como asm
, manteniendo el lenguaje similar a C99.
Estándar C99
GCC funciona así para cumplir con el estándar C99, que marca los símbolos de doble guión bajo como reservados.
Del borrador estándar C99 N1256 7.1.3 "Identificadores reservados" 1:
Cada encabezado declara o define todos los identificadores enumerados en su subcláusula asociada y, opcionalmente, declara o define los identificadores enumerados en su subcláusula de direcciones de biblioteca futura asociada e identificadores que siempre están reservados para cualquier uso o para su uso como identificadores de ámbito de archivo.
- Todos los identificadores que comienzan con un guión bajo y una letra mayúscula u otro guión bajo siempre se reservan para cualquier uso.
De lo contrario, si asm
fueron predefinidos, un programa legal como:
int asm = 0;
se volvería ilegal.
Programa de prueba
#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);
}
Probado en Ubuntu 17.10, GCC 7.2.
asm
es una extensión gcc, por lo tanto, no se puede usar con banderas como std=c99
o ansi
Más detalles en https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions