вызов функции переноса макроса с аргументами по умолчанию - PullRequest
1 голос
/ 14 мая 2019

У меня есть функция для выделения памяти, которая имеет аргумент по умолчанию для выравнивания ...

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 ]

2 голосов
/ 14 мая 2019

Используйте макрос с переменным числом аргументов и __VA_ARGS__ (C ++ 11 и более поздние версии, которые также часто поддерживаются более ранними компиляторами):

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

Обратите внимание на перестановку параметров, чтобы аргумент по умолчанию был последним.

0 голосов
/ 14 мая 2019

Это возможно с небольшим количеством препроцессорной магии (благодаря этот ответ )

Реальный трюк заключается в том, чтобы обойти тот факт, что макросы не могут быть перегружены.Эти макросы работают, используя сами аргументы для перемещения по имени другого макроса (используется для выбора перегрузки), который выбирается позицией.

Обратите внимание, что значение по умолчанию "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)

Живой пример здесь .

0 голосов
/ 14 мая 2019

Вам необходимо установить параметры по умолчанию и для этих других значений, поэтому не имеет значения, что некоторые сайты вызовов не имеют их:

void* _symalloc(int numbytes, int alignment = 32, const char* file = NULL, int line = 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...