首页 > 解决方案 > 错误:为函数提供的初始化程序,__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

我改变了$@.viafor@$@.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请参见此处,但我发现对于 g++ -根据gcc 文档- 语法是. 因此,所做的只是解析to 。--via@<your_file>@$@.via$@.via<your_file>.via

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

更新 2:

我发现了问题,并在答案部分解释了发生的事情。见下文。

标签: c++armg++

解决方案


Root cause

The problem was originated because I redefined __asm to be replaced by nothing (e.g. #define __asm) since I didn't want to touch the assembly code yet. Remember that I said I am porting ARM to x86, so I thought that easiest way to get rid of the compile errors was to remove all those __asm instructions, but not considering the effects of doing such a thing.

In other words, when I included the string.h header, the header itself uses assembly call as the error messaged pointed out:

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

and when the preprocessor changed the __asm("wcschr") for ("wcschr") the compiler hits the error -- which makes sense.

Moral of the history

Do not redefine qualifiers since it will also affect other modules that you are not seeing directly and prefer creating a macro to just change them (e.g. __asm for /*__asm*/) or just run sed in you code base.


推荐阅读