error: ‘asm’ undeclared (first use in this function)

余生长醉 提交于 2019-12-04 03:23:57
undur_gongor

You are compiling with option -std=c99.

This disables some non-standard GCC extensions like the asm feature.

See https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 for some (not very precise) documentation.

Remove or change the line set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") from your cmakefile if you need inline assembly.

Either use __asm__ instead of asm with -std=c99, or use -std=gnu99

From the GCC docs https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html

The asm keyword is a GNU extension. When writing code that can be compiled with -ansi and the various -std options, use __asm__ instead of asm (see Alternate Keywords).

and https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords:

-ansi and the various -std options disable certain keywords. This causes trouble when you want to use GNU C extensions, or a general-purpose header file that should be usable by all programs, including ISO C programs. The keywords asm, typeof and inline are not available in programs compiled with -ansi or -std (although inline can be used in a program compiled with -std=c99 or -std=c11). The ISO C99 keyword restrict is only available when -std=gnu99 (which will eventually be the default) or -std=c99 (or the equivalent -std=iso9899:1999), or an option for a later standard version, is used.

The way to solve these problems is to put __ at the beginning and end of each problematical keyword. For example, use __asm__ instead of asm, and __inline__ instead of inline.

Other C compilers won’t accept these alternative keywords; if you want to compile with another compiler, you can define the alternate keywords as macros to replace them with the customary keywords. It looks like this:

#ifndef __GNUC__
#define __asm__ asm
#endif

-pedantic and other options cause warnings for many GNU C extensions. You can prevent such warnings within one expression by writing __extension__ before the expression. __extension__ has no effect aside from this.

-std=gnu99 enables GNU extensions such as asm, while still keeping the language C99-like.

C99 standard

GCC works like this to comply with the C99 standard. From the C99 N1256 standard draft 7.1.3 "Reserved identifiers" 1:

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

Otherwise a legal program like:

int asm = 0;

would become illegal.

Test 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);
}

Tested on Ubuntu 17.10, GCC 7.2.

asm is a gcc extension, Hence you can not used with flags like std=c99 or ansi

More details at https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!