提问人:Gabriel Staples 提问时间:11/7/2023 最后编辑:Gabriel Staples 更新时间:11/8/2023 访问量:143
C++:“错误:预期为”或“...”编译 gcc 时,在“fancy_abort (__FILE__, __LINE__, __FUNCTION__)”中的“__FILE__”之前
C++: `error: expected ',' or '...' before string constant` before `__FILE__` in `fancy_abort (__FILE__, __LINE__, __FUNCTION__)` when compiling gcc
问:
这是尝试从源代码编译 Microchip XC32 微控制器 g++ XC32 v4.35 交叉编译器的免许可 GPL 版本的延续。
在这里查看我的问答,在这里查看我的回购:https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler。
请注意,这在 Linux Ubuntu 22.04 上完美地构建完成。gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
但是,在 MSYS2 UCRT64 环境中的 Windows 上编译时(按照我的说明进行设置) ,我现在收到以下错误:gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 13.2.0
gcc/gcc/system.h
./../../pic32m-source/gcc/gcc/prefix.c
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected identifier before string constant
737 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
| ^~~~~~~~
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected ',' or '...' before string constant
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected identifier before string constant
737 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
| ^~~~~~~~
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected ',' or '...' before string constant
make[1]: *** [Makefile:1112: prefix.o] Error 1
make[1]: Leaving directory '/c/Users/gabriel/GS/dev/Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-build/gcc/gcc'
make: *** [Makefile:4290: all-gcc] Error 2
这是我正在使用的 system.h
文件,位于第 737 行:
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. */
extern void fancy_abort (const char *, int, const char *)
ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
例如,在 fibonacci_heap.h
第 460 行的 C++ 模板类中调用此定义:abort()
template<class K, class V>
V*
fibonacci_heap<K,V>::delete_node (fibonacci_node<K,V> *node, bool release)
{
V *ret = node->m_data;
/* To perform delete, we just make it the min key, and extract. */
replace_key (node, m_global_min_key);
if (node != m_min)
{
fprintf (stderr, "Can't force minimum on fibheap.\n");
abort (); // <=========== HERE ===========
}
extract_min (release);
return ret;
}
如何解决此构建错误?
而且,为什么它发生在 Windows 上,而不是在 Linux 上?
其他研究:
有用的 Google 搜索:msys gcc abort fancy_abort错误:字符串常量之前的预期标识符
可能的修复:https://github.com/yosshin4004/xdev68k/blob/main/build_m68k-toolchain.sh#L199-L210
# # 新しい mingw 環境では以下のようなエラーとなる。 # ../../../src/gcc-10.2.0/gcc/system.h:743:30: error: expected identifier before string constant # 743 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) # 応急処置として、問題を起こす行を除去する。 # abort() は stdlib.h 内で宣言された実装のままの挙動となる。 # if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then cat ${SRC_DIR}/${GCC_DIR}/gcc/system.h |\ perl -e 'my $before="#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)";my $after="/* $before */";$before=quotemeta($before);while(<>){$_=~s/$before/$after/g;print $_;}' > ${SRC_DIR}/${GCC_DIR}/gcc/system.h.tmp; mv ${SRC_DIR}/${GCC_DIR}/gcc/system.h.tmp ${SRC_DIR}/${GCC_DIR}/gcc/system.h fi
# # In the new mingw environment, the following error will occur. # ../../../src/gcc-10.2.0/gcc/system.h:743:30: error: expected identifier before string constant # 743 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) # As a workaround, remove the offending line. # abort() behaves as the implementation declared in stdlib.h.
上面的代码只是在 中找到 ,并将其注释为 ,从而将其删除。
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
gcc/system.h
/* #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) */
只是注释掉这个令人反感的宏定义似乎真的很骇人听闻。我不完全理解这种变化的影响。
答:
非常感谢 @Tim Roberts 和“@n. m. could be an AI”在问题下的帮助和评论,促成了这个答案。
溶液:
注释掉 system.h
中的 abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) #define
以使 gcc 编译。
简单地注释掉定义,就像这里所做的那样,正如我的问题底部所记录的那样,是有效的。abort()
Windows 中的 MSYS2 中似乎存在一个错误,阻止构建与它定义的构建一起工作,因此只需打开,在第 737 行找到它:xc32-v4.35-src/pic32m-source/gcc/gcc/system.h
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
...并像这样注释它:
/* #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) */
现在,当我运行时,构建完成,MSYS2 UCRT64 gcc 工具链能够构建 PIC32 mcu gcc 交叉编译器完成!time Microchip_XC32_Compiler/build-xc32-v4.35m.sh
这个黑客安全吗?
是的,我们是这么认为的。
这里有 3 层:我在 Windows(第 1 层)上使用 MSYS2 UCRT GCC 编译器来编译 Microchip XC32 PIC32 gcc 微控制器交叉编译器(第 2 层),它将交叉编译 PIC32 微控制器(第 3 层)的程序(在本问答中在 Windows 上,尽管我也在 Linux Ubuntu 上构建了它)。
根据在我的问题下与 @Tim Roberts 的讨论(例如,此评论和其他评论),我们认为此更改是相当良性的,并且应该只影响第 2 层 XC32 交叉编译器(这是本问答中正在编译的内容),如果它在运行和编译第 3 层目标时崩溃,则会生成不太有用的运行时错误消息(缺少内容)。所以,没什么大不了的。第 3 层(目标 MCU)不受影响。如果第 2 层崩溃,它只会有不太有用的错误消息。但是,这不太可能。我不记得 gcc 编译器曾经在我身上崩溃过。当然,它在编译时产生了大量的编译错误,但我不记得曾经见过它产生运行时崩溃并输出自己的内部错误。这就是我们正在谈论的。这就是我的更改影响的部分。__FILE__, __LINE__, __FUNCTION__
其他修复
SourceForge 上的 Tony Yu 在这里也有一个看起来不错的替代修复程序。
基本上,就像我所做的那样,只需注释掉 ,然后也将所有对 in 的调用替换为 代替。这里的挑战是替换所有正确的呼叫,不仅在这里,而且在他们可能呼叫的任何地方。所以。。。这似乎很难。我认为只是把它注释掉就可以了。👍#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
system.h
abort()
gcc/gcc.c
fancy_abort (__FILE__, __LINE__, __FUNCTION__)
abort()
fancy_abort()
错误报告
我打开了这个错误报告。欢迎发表评论: https://github.com/msys2/MSYS2-packages/issues/4142
更新:更好的修复
将此修补程序应用于一堆 gcc 文件:https://gcc.gnu.org/pipermail/gcc-patches/2023-January/609514.html。此链接来自对我上面错误报告的回复。
基本上,在调用 #include < windows.h>
之前,应始终 #define WIN32_LEAN_AND_MEAN
。显然,这是正确的解决方法。
原因:从这里开始:https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=902c755930326cb4405672aa3ea13c35c653cbff(强调后加):
始终在之前定义
WIN32_LEAN_AND_MEAN
<windows.h>
最近,mingw-w64 已从 Wine 中更新,其中包括 间接由 if 未定义。该类有一个名为 的成员函数,它得到 受“system.h”中的宏影响。
<msxml.h>
<windows.h>
WIN32_LEAN_AND_MEAN
IXMLDOMDocument
abort()
abort()
WIN32_LEAN_AND_MEAN
然而,应该始终被定义。这 可以排除“API”,例如加密、DDE、RPC、Shell 和 Windows 套接字的 [1],并稍微加快了这些文件的编译速度。
因此,我计划手动执行修复,生成基于补丁的文件,提交补丁文件,然后作为构建脚本过程的一部分通过(请参阅此处的答案)制作补丁。git diff
git apply
评论
abort()
#define abort()
#define
abort