Error: Initializer provided for function, __THROW __asm

Error: Initializer provided for function, __THROW __asm

我正在尝试移植要使用 x86_64 C++ 编译的 ARM-C 库,但出现以下错误:

In file included from /usr/include/c++/5/cwchar:44:0,
                 from /usr/include/c++/5/bits/postypes.h:40,
                 from /usr/include/c++/5/bits/char_traits.h:40,
                 from /usr/include/c++/5/string:40,
                 from MyFile.h:19,
/usr/include/wchar.h:226:20: error: initializer provided for function
       __THROW __asm ("wcschr") __attribute_pure__;
                     ^

其中 MyFile.h 具有以下结构

// comments
#pragma once
// comments
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string>              //<<< line 19

…

最初,它给了我一个类似的错误:

In file included from MyFile.h:19:
/usr/include/string.h:73:21: error: initializer provided for function
          __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
                        ^

编译器版本:

GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.11) version 5.4.0 20160609 (x86_64-linux-gnu)
           compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3
ldd (Ubuntu GLIBC 2.23-0ubuntu11) 2.23

编译标志:

#g++ -O3 -std=c++14 -fpermissive -Wno-system-headers -w

更新 1:

我一直在修改Makefile,原版包含$@.via。例如:

@$(COMPILE) -M -MF $(subst .o,.d.tmp,$@) -MT $@ -E $(C_FLAGS) $@.via $< -o $@.preprocessed.c

并且我将 $@.via 更改为 @$@.via,因为我在一个较旧的项目中看到他们是这样做的。但是,如果我离开 $@.via 我只会得到:

SomeFile.c:1:1 fatal error: OneHeader.h: No such file or directory

我开始觉得我的 Makefile 哪里不对...

我误解了编译器选项...上面几行,我的 makefile 创建了 @.via 文件传递​​ DEFINESINCLUDES

       @echo $(patsubst %, '%', $(C_DEFINES)) > $@.via
       @echo $(C_INCLUDE) >> $@.via

和那些 @.via 文件作为编译的附加参数传递。虽然 armcc 支持 --via see here, I found that for g++ -according to the gcc doc- 语法是 @<your_file>。因此,@$@.via 所做的只是将 $@.via 解析为 <your_file>.via.

现在我仍然收到 initializer provided for function 错误消息。

更新 2:

我发现了问题,我在答案部分解释了发生了什么。见下文。

根本原因

问题的起因是我重新定义了 __asm 以替换任何内容(例如 #define __asm),因为我还不想触及汇编代码。请记住,我说过我正在将 ARM 移植到 x86,所以我认为消除编译错误的最简单方法是删除所有这些 __asm 指令,但没有考虑这样做的影响。

换句话说,当我包含 string.h header 时,header 本身使用汇编调用,因为错误消息指出:

/usr/include/wchar.h:226:20: error: initializer provided for function
       __THROW __asm ("wcschr") __attribute_pure__;

并且当预处理器将 __asm("wcschr") 更改为 ("wcschr") 时,编译器会遇到错误——这是有道理的。

历史的寓意

不要重新定义限定符,因为它也会影响您没有直接看到的其他模块,并且更喜欢创建一个宏来仅更改它们(例如 __asm 用于 /*__asm*/)或只是 运行 sed 在你的代码库中。