c++ 使用x-macros定义匿名枚举产生编译错误

kb5ga3dv  于 2022-12-01  发布在  Mac
关注(0)|答案(2)|浏览(141)

我正在做一个大项目,我有很多错误宏。
我想为记录器编写一个帮助函数,将每个errno字符串化为一个字符串。我决定使用x宏,但我得到编译错误
首先,代码是这样的:

// project_errno.h
#define PROJECT_ERR_KEY_FAILURE                         12222
#define PROJECT_ERR_CIPHER_ZERO_PADDING                 12345
#define PROJECT_ERR_FAILED_TO_SETUP_ENC_KEY             14004

我是这样整理的:

  • 在另一个文件中,我放置了x-macros:
// project_errno.hx
PROJECT_ERR_FUNC(PROJECT_ERR_KEY_FAILURE)                         12222
PROJECT_ERR_FUNC(PROJECT_ERR_CIPHER_ZERO_PADDING)                 12345
PROJECT_ERR_FUNC(PROJECT_ERR_FAILED_TO_SETUP_ENC_KEY)             14004
  • 然后我把它变成了一个枚举:
// project_errno.h
enum {
#define PROJECT_ERR_FUNC(name, value) name=value,
#include "project_errno.hx"
#undef PROJECT_ERR_FUNC
};
  • 然后我添加了一个将由记录器使用的函数:
// logging.h (declaration) and (definition) logging.c
const char* stringify_errno(int errno) {
    switch (errno) {
#define PROJECT_ERR_FUNC(name, value) case name: return #value ;
#include "project_errno.hx"
#undef PROJECT_ERR_FUNC
    }
}

所以,看起来很不错,但我不能让它编译,我得到以下编译错误:

project_errno.h:8:53: error: error: expected identifier before numeric constant
#define PROJECT_ERR_CIPHER_ZERO_PADDING                 12345
                                                        ^
..../project_errno.h:17:30: note: in definition of macro ‘PROJECT_ERR_FUNC’
#define PROJECT_ERR_FUNC(name, value) name=value,
                                      ^~~~
..../project_errno.hx:47:14: note: in expansion of macro ‘PROJECT_ERR_CIPHER_ZERO_PADDING ’PROJECT_ERR_FUNC(PROJECT_ERR_CIPHER_ZERO_PADDING,       12345)

project_errno.h:8:53: error: error: expected ‘}’ before numeric constant 
#define PROJECT_ERR_CIPHER_ZERO_PADDING                 12345
                                                        ^
..../project_errno.h:17:30: note: in definition of macro ‘PROJECT_ERR_FUNC’
#define PROJECT_ERR_FUNC(name, value) name=value,
                                      ^~~~
..../project_errno.hx:47:14: note: in expansion of macro ‘PROJECT_ERR_CIPHER_ZERO_PADDING ’PROJECT_ERR_FUNC(PROJECT_ERR_CIPHER_ZERO_PADDING,       12345)

project_errno.h:8:53: error: expected unqualified-id before numeric constant 
#define PROJECT_ERR_CIPHER_ZERO_PADDING                 12345
                                                        ^
..../project_errno.h:17:30: note: in definition of macro ‘PROJECT_ERR_FUNC’
#define PROJECT_ERR_FUNC(name, value) name=value,
                                      ^~~~
..../project_errno.hx:47:14: note: in expansion of macro ‘PROJECT_ERR_CIPHER_ZERO_PADDING ’PROJECT_ERR_FUNC(PROJECT_ERR_CIPHER_ZERO_PADDING,       12345)
                  ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ......../project_errno.h:20:1: error: expected declaration before ‘}’ token
};
^

..../project_errno.h:17:30: note: in definition of macro ‘PROJECT_ERR_FUNC’
#define PROJECT_ERR_FUNC(name, value) name=value,
                                      ^~~~
..../project_errno.hx:47:14: note: in expansion of macro ‘PROJECT_ERR_CIPHER_ZERO_PADDING ’PROJECT_ERR_FUNC(PROJECT_ERR_CIPHER_ZERO_PADDING,       12345)
                  ^~~~~~~~~~~~~~~~~~~~~~~

我不明白为什么我得到这些错误(我在同一个编译会话中多次收到相同的错误信息),我希望你们能帮助我。另外,如果你们有任何其他的解决方案来解决我最初打算解决的问题(使用errno宏并添加一个函数来字符串化那些errno,无论何时我添加一个errno到项目中[仅在一个地方]),我很想听听谢谢

ni65a41a

ni65a41a1#

我会按照维基百科page中关于X宏的食谱:

    • 实施**

X宏应用程序由两部分组成:
1.列表元素的定义。
1.扩展列表以生成声明或语句的片段。
该列表由宏或头文件定义(名为LIST),它本身不会产生程式码,而仅仅由一系列宏调用组成LIST的每次扩展之前都有一个X的定义,该定义带有列表元素的语法。LIST的调用为列表中的每个元素扩展X
特别是第二个例子,以X宏作为参数的例子
将工作宏的名称传递到列表宏中。这既避免了定义名称模糊的宏(X),也减少了取消定义它的需要。
在OP的用例中,这将导致以下三个文件:
第一个
可在此处测试:https://wandbox.org/permlink/aNJCI7lQihkFnYzp

mec1mxoz

mec1mxoz2#

何丽答:
我能够使用

enum {
#define PROJECT_ERR_FUNC(name) , name =
PROJECT_ERR_START_OF_ENUM = -1
#include "project_errno.hx"
#undef PROJECT_ERR_FUNC
};

但是必须删除project_errno.hx末尾的反勾号。上面的代码只有在之前不包含project_errno.h的情况下才能工作。
一个完整的最低工作计划将是

enum {
#define PROJECT_ERR_FUNC(name) , name =
PROJECT_ERR_START_OF_ENUM = -1
#include "project_errno.hx"
#undef PROJECT_ERR_FUNC
};

#include <iostream>

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

将打印12222

相关问题