【问题标题】:error: ‘asm’ undeclared (first use in this function)错误:“asm”未声明(在此函数中首次使用)
【发布时间】:2016-05-09 22:51:33
【问题描述】:

我在编译过程中收到以下错误:

error: ‘asm’ undeclared (first use in this function)
 EXCHANGE( s, *(a) );
 ^

在调用宏的头文件中如下:

EXCHANGE( s, *(a) );

而宏的实际定义如下:

#define EXCHANGE(R,M) asm volatile ( "xchg   %1, %0" : "+m" (M), "+r" (R) )

宏调用和定义存在同一个头文件中。 怎么了?

我正在使用CMAKE构建项目,CFLAGS如下:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-default")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
#-Wno-deprecated-declarations to suppress the deprecation errors with newer version of JSON-C 
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wbad-function-cast")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-overflow=5")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winline")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wundef")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wnested-externs")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-cast-qual")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunreachable-code")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wfloat-equal")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-aliasing=2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wredundant-decls")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wold-style-definition")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")

#set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -O0 -g3 -ggdb")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -E")

【问题讨论】:

  • 您是否尝试在使用-E 进行预处理后停止编译?
  • 您的编译器是否支持 asm 关键字。顺便说一句,您使用的是哪个编译器/环境/IDE/OS?
  • @Black_Zero:请在您的问题中明确说明。
  • 你目前的 CFLAGS 是什么?
  • -std=c99 更改为-std=gnu99

标签: c linux gcc inline-assembly


【解决方案1】:

要么使用__asm__ 代替asm-std=c99,要么使用-std=gnu99

来自 GCC 文档 https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html

asm 关键字是 GNU 扩展。编写可使用 -ansi 和各种 -std 选项编译的代码时,请使用 __asm__ 而不是 asm(请参阅备用关键字)。

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

-ansi 和各种 -std 选项禁用某些关键字。当您想要使用 GNU C 扩展或应该由所有程序(包括 ISO C 程序)使用的通用头文件时,这会导致麻烦。关键字 asm、typeof 和 inline 在使用 -ansi 或 -std 编译的程序中不可用(尽管 inline 可以在使用 -std=c99 或 -std=c11 编译的程序中使用)。 ISO C99 关键字限制仅在使用 -std=gnu99(最终将成为默认值)或 -std=c99(或等效的 -std=iso9899:1999)或更高标准版本的选项时可用。

解决这些问题的方法是将__放在每个有问题的关键字的开头和结尾。例如,使用 __asm__ 代替 asm,使用 __inline__ 代替 inline。

其他 C 编译器不接受这些替代关键字;如果您想用另一个编译器编译,您可以将备用关键字定义为宏,以用惯用的关键字替换它们。它看起来像这样:

#ifndef __GNUC__
#define __asm__ asm
#endif

-pedantic 和其他选项会导致许多 GNU C 扩展出现警告。您可以通过在表达式前写入__extension__ 来防止在一个表达式中出现此类警告。 __extension__除此之外没有任何作用。

-std=gnu99 启用 GNU 扩展,例如 asm,同时仍保持类似 C99 的语言。

C99 标准

GCC 这样做是为了符合 C99 标准,该标准将双下划线符号标记为保留。

来自C99 N1256 standard draft 7.1.3“保留标识符”1:

每个标题声明或定义其相关子条款中列出的所有标识符,并且 可选地声明或定义在其关联的未来库方向中列出的标识符 始终保留用于任何用途或用作文件的子条款和标识符 范围标识符。

  • 以下划线和大写字母或其他字母开头的所有标识符 下划线始终保留用于任何用途。

否则,如果 asm 是预定义的,则合法程序如下:

int asm = 0;

会变成非法的。

测试程序

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

在 Ubuntu 17.10、GCC 7.2 上测试。

【讨论】:

    【解决方案2】:

    您正在使用选项 -std=c99 进行编译。

    这会禁用一些非标准的 GCC 扩展,例如 asm 功能。

    请参阅https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 获取一些(不是很精确的)文档。

    如果您需要内联汇编,请从您的 cmakefile 中删除或更改 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") 行。

    【讨论】:

    • 这是一个评论而不是一个答案。
    • 很好,这就是我在询问编译标志时发现的。很高兴我们找到了它。
    • 可以将-ansi-std=c99-ansi -pedantic 等标志与__asm__ 一起使用,而不是asm。因为__xx 是扩展名。标准允许扩展。参考:gcc.gnu.org/onlinedocs/gcc/…
    【解决方案3】:

    asm 是 gcc 扩展,因此您不能与 std=c99ansi 等标志一起使用

    更多详情见 https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions

    【讨论】:

      猜你喜欢
      • 2018-10-03
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多