- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
前段时间写了一组X-macros对于一个大项目。我需要维护字符串和枚举引用/哈希值/回调函数等的连贯列表。这是函数回调的样子
#define LREF_LOOKUP_TABLE_TEXT_SIZE 32
#define _LREF_ENUM_LIST(_prefix,_ref,...) _prefix ## _ ## _ref,
#define _LREF_BASE_STRUCT_ENTRY(_prefix,_ref) .text= #_ref "\0", .position= _LREF_ENUM_LIST(_prefix, _ref)
#define _LREF_FUNCTION_STRUCT_LIST(_prefix,_ref,...) {_LREF_BASE_STRUCT_ENTRY(_prefix,_ref) _prefix ## _ ## _ref ## _callback},
#define _LREF_ENUM_TYPEDEF(_prefix) \
typedef enum _prefix \
{ \
_ ## _prefix ## s(_prefix,_LREF_ENUM_LIST) \
_LREF_ENUM_LIST(_prefix,tblEnd) \
} e_ ## _prefix
#define _LREF_LOOKUP_TABLE_TYPEDEF(_prefix, _extras) \
typedef struct _prefix ## _lookup \
{ \
const char text[LREF_LOOKUP_TABLE_TEXT_SIZE]; \
e_ ## _prefix position; \
_extras \
} _prefix ##_lookup_t
#define LREF_GENERIC_LOOKUP_TABLE(_prefix, _type, _tabledef, _listdef, _extras) \
_LREF_ENUM_TYPEDEF(_prefix); \
_LREF_LOOKUP_TABLE_TYPEDEF(_prefix,_tabledef); \
_extras \
_LREF_LOOKUP_TABLE_DECLARATION(_prefix,_listdef, _type)
#define LREF_FUNCTION_LOOKUP_TABLE(_prefix, _type) \
_ ## _prefix ## s(_prefix, _LREF_FUNCTION_DEF ) \
LREF_GENERIC_LOOKUP_TABLE( _prefix, \
_type, \
void* (*function) (void*);, \
_LREF_FUNCTION_STRUCT_LIST, )
这位于头文件中,允许我编写如下内容:
#define _cl_tags(x,_) \
_(x, command_list) \
_(x, command) \
_(x, parameter) \
_(x, fixed_parameter) \
_(x, parameter_group) \
_(x, group) \
_(x, map) \
_(x, transform)
LREF_FUNCTION_LOOKUP_TABLE(cl_tag, static);
这使处理例程变短。例如,加载带有上述标签的配置文件很简单:
for (node_tag = cl_tag_lookup_table; node_tag->position != cl_tag_tblEnd; node_tag++)
{
if (strcasecmp(test_string, node_tag->text) == 0)
{
func_return = node_tag->function((void*)m_parser);
}
}
我的问题是:我讨厌必须在我的 #define
中包含第二个参数。我希望能够编写 #define _cl_tags(_)
而不是 #define _cl_tags(x,_)
。如您所见,x
仅用于向下传递前缀 (cl_tag)。但这是多余的,因为前缀是初始宏的参数。
如果我的预处理器首先扩展最外层的宏,那么解决这个问题会很容易。不幸的是,GCC 的预处理器在扩展最外层的宏之前处理最内层的宏,即参数值。
我正在使用 gcc 4.4.5
澄清按照C89(和C99)标准,定义如下
#define plus(x,y) add(y,x)
#define add(x,y) ((x)+(y))
调用
plus(plus(a,b),c)
应该屈服
plus(plus(a,b),c)
添加(c,plus(a,b))
((c)+(plus(a,b))
((c)+(add(b,a))
((c)+(((b)+(a))))
gcc 4.4.5 给出
plus(plus(a,b),c)
plus(add(b,a),c)
plus(((b)+(a)),c)
添加(c,((b)+(a)))
((c)+(((b)+(a))))
最佳答案
这是我会做的(做过类似的):
将这些放在实用程序头文件中:
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
然后在包含 LREF 宏头文件之前定义它:
#define LREF_TAG cl_tag
然后,在你的 LREF 宏头文件中,
#define LREF_PFX(x) PPCAT(LREF_TAG, x)
#define LREF_SFX(x) PPCAT(x, LREF_TAG)
然后将 _prefix ## foo
的每个实例替换为 LREF_PFX(foo)
并将 foo ## _prefix
的每个实例替换为 LREF_SFX(foo )
。
(将两个以上的标记粘贴在一起时,只需使用嵌套的 PPCAT。)
你的调用将变成
#define LREF_TAG cl_tag
#define _cl_tags(_) \
_(command_list) \
_(command) \
_(parameter) \
_(fixed_parameter) \
_(parameter_group) \
_(group) \
_(map) \
_(transform)
LREF_FUNCTION_LOOKUP_TABLE(static);
关于c - 如何消除一个多余的宏参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5066813/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!