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

时间:2019-05-14 00:34:22

标签: c++ macros

我有一个分配内存的函数,它有一个默认的对齐参数...

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)

但是现在的问题是,所有未对齐传递的呼叫者都被打断了,其中有数百个。

是否可以通过某种方式让此支持传递对齐方式,或者在两种情况下都提供文件/行?

3 个答案:

答案 0 :(得分:2)

使用可变参数宏和__VA_ARGS__(C ++ 11和更高版本,并且早期版本的编译器也经常支持):

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

请注意参数的重新排列,以使默认参数位于最后一个参数上。

答案 1 :(得分:0)

您还需要为其他值设置默认参数,因此,某些呼叫站点没有默认值也没关系:

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

答案 2 :(得分:0)

可以使用一些预处理器魔术(感谢this answer

真正的技巧是解决宏不能重载这一事实。这些宏通过使用参数本身来移动根据位置选择的另一个宏的名称(用于选择重载)。

请注意,默认值“ 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)

Live example here