带有默认参数的宏包装函数调用

macro wrapping function call with default arguments

本文关键字:包装 函数调用 参数 默认      更新时间:2023-10-16

我具有分配内存的函数,该函数具有对齐的默认参数...

void* symalloc(int numbytes, int alignment=32)

我想从呼叫位置获取传递的文件/行号。所以,我将其更改为...

void* _symalloc(int numbytes, int alignment, const char* file, int line);
#define symalloc(numbytes, alignment) _symalloc(numbytes, alignment, __FILE__, __LINE)

但是现在问题是所有未通过对齐方式的呼叫者都被打破了,并且有数百个呼叫者。

是否有某种方法可以通过对准是否通过对齐,并且在任何一种情况下都提供文件/行?

使用variadic宏和 __VA_ARGS__(C 11及以后,并且通常也得到早期编译器的支持(:

void symalloc_(const char* file, int line, int numbytes, int alignment=32);
#define symalloc(...) (symalloc(__FILE__, __LINE__, __VA_ARGS__))

注意参数的重排,以便默认参数在最后一个。

您还需要为其他值放置默认参数,因此某些呼叫站点没有它们的情况并不重要:

void* _symalloc(int numbytes, int alignment = 32, const char* file = NULL, int line = 0);

有可能使用一些预处理器魔术(感谢此答案(

真正的技巧是解决宏不能超载的事实。这些宏通过使用参数本身来围绕另一个宏的名称(用于选择过载(的名称来起作用,该宏是由位置选择的。

请注意,默认值" 32"出现在SYMALLOC1宏内。

#include <iostream>
void* symalloc_impl(int numbytes, int alignment, const char* file, int line){
    std::cout << file << ':' << line << "> symalloc(" << numbytes << ", " << alignment << ")n";
    return nullptr;
}
#define SYMALLOC1(numbytes) symalloc_impl(numbytes, 32, __FILE__, __LINE__)
#define SYMALLOC2(numbytes, alignment) symalloc_impl(numbytes, alignment, __FILE__, __LINE__)
#define SYMALLOC_DISPATCH(_1,_2,NAME,...) NAME
#define symalloc(...) SYMALLOC_DISPATCH(__VA_ARGS__,SYMALLOC2,SYMALLOC1,UNUSED)(__VA_ARGS__)
int main() {
    symalloc(16);
    symalloc(64, 8);
    return 0;
}

示例输出:

main.cpp:15> symalloc(16, 32)

main.cpp:17> symalloc(64, 8)

在这里实时示例。