gpt4 book ai didi

c++ - 为什么 gcc 在递归扩展宏时中断

转载 作者:太空狗 更新时间:2023-10-29 21:34:54 25 4
gpt4 key购买 nike

你好,

我在编译利用递归宏扩展的非常简单的 C++ 程序时遇到了一个奇怪的问题:

#define FINAL(a1, a2, a3) const char *p = "final values are: " #a1 " " #a2 " " #a3;

#define SPLIT(a1, a2) a1, a2
#define BRACES(a1, a2) ( a1, a2 )
#define START(macro, a1, a2) macro BRACES(a1, SPLIT a2)

START(FINAL, 1, (2, 3))

int main(int argc, char* argv[])
{
std::cout << p << std::endl;
return 0;
}

该程序期望打印“最终值为:1 2 3”文本。它在 Visual Studio 2008 上执行。

但是我在尝试使用 Windows 7 上的 mingw32 gcc-6.3 和 Linux Ubuntu-16 上的 gcc-5.4 编译它时发现一个问题:

$ g++ -I /e/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60 test.cpp
test.cpp:7:24: error: expected constructor, destructor, or type conversion before '(' token
#define BRACES(a1, a2) ( a1, a2 )
^
test.cpp:8:36: note: in expansion of macro 'BRACES'
#define START(macro, a1, a2) macro BRACES(a1, SPLIT a2)
^~~~~~
test.cpp:12:1: note: in expansion of macro 'START'
START(FINAL, 1, (2, 3))
^~~~~

看起来它不依赖于 C++ 标准,我已经尝试使用 gcc -std=c++11 和 -std=c++03。我已经多次重读 C++ 11 标准的第 16.3 部分“宏替换”,但我想我错过了一些重要的东西。

这里的代码可能有什么问题?

还有一个重要的事情:boost 预处理器库中的 BOOST_PP_SEQ_FOR_EACH_I_R 也无法编译,这很奇怪:

#include <iostream>
#include <boost/preprocessor/seq/for_each_i.hpp>

#define FINAL2(r, data, id, value) const char *p ## id = #value;
BOOST_PP_SEQ_FOR_EACH_I_R(_, FINAL2, _, (a)(b)(c))

int main()
{
std::cout << p1 << std::endl;
return 0;
}

错误输出:

$ g++ -I /e/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60 -std=c++03 test2.cpp
In file included from test2.cpp:2:0:
E:/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60/boost/preprocessor/seq/for_each_i.hpp:96:96: error: expected constructor, destructor, or type conversion before '(' token
# define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq, 0, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
^
E:/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60/boost/preprocessor/control/iif.hpp:32:31: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC'
# define BOOST_PP_IIF_1(t, f) t
^
E:/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60/boost/preprocessor/control/iif.hpp:25:39: note: in expansion of macro 'BOOST_PP_IIF_1'
# define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_ ## bit(t, f)
^~~~~~~~~~~~~

最佳答案

第一个示例的问题似乎相当简单。第一次扩展预处理后将停止做你想让它做的事情:

START(FINAL, 1, (2, 3))
// becomes
FINAL BRACES(1, SPLIT (2, 3))

FINAL 没有参数,所以生成的代码会乱七八糟。

关于c++ - 为什么 gcc 在递归扩展宏时中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44864952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com