#是否在程序集文件中包含带有C声明的标头而不出错?
我有一个汇编文件(#是否在程序集文件中包含带有C声明的标头而不出错?,c,gcc,assembly,include,x86,C,Gcc,Assembly,Include,X86,我有一个汇编文件(asm.S),它需要在C头文件(C#decls.h)中定义一个常量。头文件除了我想要的#define之外还包含C函数声明。不幸的是,gcc在尝试编译程序集文件时会出错。比如说, c_decls.h #ifndef __c_decls_h__ #define __c_decls_h__ #define I_NEED_THIS 0xBEEF int foo(int bar); #endif asm.S #include "c_decls.h" .globl main mai
asm.S
),它需要在C头文件(C#decls.h
)中定义一个常量。头文件除了我想要的#define
之外还包含C函数声明。不幸的是,gcc
在尝试编译程序集文件时会出错。比如说,
c_decls.h
#ifndef __c_decls_h__
#define __c_decls_h__
#define I_NEED_THIS 0xBEEF
int foo(int bar);
#endif
asm.S
#include "c_decls.h"
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl $I_NEED_THIS, %eax
leave
ret
输出
>gcc-m32 asm.Sc_decls.h:汇编程序消息:
c_decls.h:6:错误:表达式后的“垃圾”(int bar)
c_decls.h:6:错误:后缀或操作数对于“int”无效
有没有办法在汇编文件中包含包含函数声明的C头文件?(更改标题或移动/重新定义
#define
不是一个选项。)使用-dM
选项cpp
只从标题文件中获取#define,并包含该文件
cpp -dM c_decls.h > bare_c_decls.h
现在在.S文件中包括bare\u c\u decls.h
。如果无法更改.S文件中的#include,请在另一个目录中生成裸头文件,并将该include路径放在编译器/汇编程序命令行中,然后再执行其他操作
最后,您可以将所有这些都打包到一个生成文件中,以便自动生成“裸”头文件。这很简单:
在.S文件中使用
#define __ASSEMBLY__
在.C文件中使用
#undef __ASSEMBLY__
然后在.h文件中放置条件
#ifdef __ASSEMBLY__
// here declarations only for assembler
#else
// here only for C
#endif
// and here - defines suitable for both
(更改标题或移动/重新定义#define不是一个选项。)鉴于您取消了最合理选项的资格,我认为您运气不好。:-)考虑到标头正在调用未定义的行为(使用以双下划线开头的名称作为其多重包含保护),我认为您应该重新考虑不更改它的要求。:-)标题应包含“C”类的include、
#include my_defs.h
,而不是像类的“ASM”。include my_defs.h
。在最后一种情况下,asm解析器将忽略#ifdef
,#else
,#endif
。只是无意中发现了这个…gcc foo.S
已经将\uuu汇编程序\uuu
预先定义为1。所以你可以用#ifndef uuu汇编程序uuu
简单的-dM
来保护你所有的纯C语言的东西。它什么也不返回-E-dM
转储所有定义,包括头中定义的定义。唯一不方便的是,列表中有700多个定义。您使用的是什么版本的cpp?(注意,这个问题与gcc有关)它是GNU gcc,arm-none-eabi-g++(用于arm嵌入式处理器的GNU工具)4.9.3 20150529(发行版)
@user3124812:您可能运行了gcc-dM
,而不是cpp-dM
。您应该将gcc-E-dM
与您通常使用的所有其他编译选项一起使用,以确保标题中的所有#ifdef
都获得相同的预定义宏。(例如,如果在x86目标上构建-mavx
与不构建-mavx
时,您的头中可能有\ifdef\uuuuuu AVX\uuuu
),那么我建议不要直接使用cpp
。