Vous compilez avec l'option -std=c99
.
Cela désactive certaines extensions GCC non standard comme le asm
fonctionnalité.
Voir https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 pour une documentation (pas très précise).
Supprimer ou modifier la ligne set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
à partir de votre cmakefile si vous avez besoin d'un assemblage en ligne.
Soit utiliser __asm__
au lieu de asm
avec -std=c99
, ou utilisez -std=gnu99
À partir de la documentation GCC https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html
Le mot clé asm est une extension GNU. Lorsque vous écrivez du code qui peut être compilé avec -ansi et les diverses options -std, utilisez
__asm__
au lieu de asm (voir Mots-clés alternatifs).
et https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords :
-ansi et les diverses options -std désactivent certains mots clés. Cela cause des problèmes lorsque vous souhaitez utiliser des extensions GNU C ou un fichier d'en-tête à usage général qui devrait être utilisable par tous les programmes, y compris les programmes ISO C. Les mots clés asm, typeof et inline ne sont pas disponibles dans les programmes compilés avec -ansi ou -std (bien que inline puisse être utilisé dans un programme compilé avec -std=c99 ou -std=c11). Le mot-clé ISO C99 restrict n'est disponible que lorsque -std=gnu99 (qui sera éventuellement la valeur par défaut) ou -std=c99 (ou l'équivalent -std=iso9899:1999), ou une option pour une version standard ultérieure, est utilisé.
La façon de résoudre ces problèmes est de mettre
__
au début et à la fin de chaque mot-clé problématique. Par exemple, utilisez__asm__
au lieu de asm, et__inline__
au lieu d'être en ligne.Les autres compilateurs C n'accepteront pas ces mots clés alternatifs ; si vous souhaitez compiler avec un autre compilateur, vous pouvez définir les mots-clés alternatifs comme des macros pour les remplacer par les mots-clés habituels. Il ressemble à ceci :
#ifndef __GNUC__ #define __asm__ asm #endif
-pedantic et d'autres options provoquent des avertissements pour de nombreuses extensions GNU C. Vous pouvez empêcher de tels avertissements dans une expression en écrivant
__extension__
avant l'expression.__extension__
n'a aucun effet en dehors de cela.
-std=gnu99
active les extensions GNU telles que asm
, tout en conservant le langage de type C99.
Norme C99
GCC fonctionne ainsi pour se conformer à la norme C99, qui marque les symboles de double trait de soulignement comme réservés.
Extrait du projet de norme C99 N1256 7.1.3 "Identifiants réservés" 1 :
Chaque en-tête déclare ou définit tous les identifiants répertoriés dans sa sous-clause associée, et éventuellement déclare ou définit les identifiants répertoriés dans sa future sous-clause de directions de bibliothèque associée et les identifiants qui sont toujours réservés soit pour une utilisation quelconque, soit pour être utilisés comme identifiants de portée de fichier.
- Tous les identifiants qui commencent par un trait de soulignement et soit une lettre majuscule soit un autre trait de soulignement sont toujours réservés à toute utilisation.
Sinon, si asm
ont été prédéfinis, un programme légal comme :
int asm = 0;
deviendrait illégal.
Programme de test
#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);
}
Testé sur Ubuntu 17.10, GCC 7.2.
asm
est une extension gcc, vous ne pouvez donc pas l'utiliser avec des drapeaux comme std=c99
ou ansi
Plus de détails sur https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions