Препроцессор C: #define макрос, который можно вызвать без круглых скобок

Мне было интересно, можно ли написать макрос, который ведет себя следующим образом:

void Func(int x)
{
    printf("%d",x);
}

#define func Func x //or something

int main()
{
    func 10; //<---- remove parenthesis
}

В этом случае func укажет на действительную функцию func, а 10 будет ее аргументом без скобок.

Я пытаюсь добиться чего-то похожего на оператор new в С++, но в C.

Пример:

class Base* b = new(Base);

В этом случае class является макросом для struct, new - это функция, которая принимает указатель на функцию, а Base - это функция, которая выделяет память для struct Base.

Я хотел бы переписать код на что-то вроде этого:

class Base* b = new Base;

Что будет возможно, если я смогу найти макрос:)

Ответ 1

Достаточно смешно вы можете просто определить new away (#define new) и определить токен для каждой конструктор-подобной функции, которая выдает реальный вызов функции с помощью скобок, например #define BASE Base().

Это должно сделать следующий код законным C:

#define new
#define class struct
#define BASE Base()

// forward declaration
class Base;
extern class Base *Base();

void f()
{
    class Base* b = new BASE;
}

Ответ 2

Я не думаю, что вы можете делать то, что хотите. Если у вас есть макрос с параметром, например #define func(x) Func(x), вам нужно вызвать его, как вы бы вызвали функцию:

#define func(x) Func(x)
func(x) // Will be replaced by Func(x) during pre-processing

Если у вас есть макрос без параметра, то при предварительной обработке значение просто заменяется:

#define MY_VAL 110
func(MY_VAL) // Will be replaced by Func (110) during pre-processing

Легко удалить первую скобку...

#define func Func(
func 10);

... отлично, но довольно странно. Я не думаю, что есть способ удалить закрывающий кронштейн, к сожалению.

Как отметил Йоахим Пилеборг в своих комментариях, я не вижу веских оснований для этого в реальной программе C.