连接预处理器标记

问题描述 投票:0回答:3

如何编写宏

#define CONCATENATE(x)
将产生以下结果:

CONCATENATE(int); // Produce --> int
CONCATENATE(unsigned int); // Produce --> unsignedint
CONCATENATE(long long int); // Produce --> longlongint
etc.

结果可能与我上面写的不同。唯一的要求是结果是单个标记。我需要它是一个单一的标记,因为这个标记将用于定义一个名称包含这个标记的函数,例如

void Foo_longlongint(void);

编辑

我想使用一些宏技巧来创建通用函数。例如,假设我们要声明一个通用缓冲区:

#define DECLARE(type, size) struct {type buffer[size];}

现在我想为许多可能的类型创建函数,例如:

#define DEFINE_FUNCTION(type)                                 \
void Buffer_##type##_Add(size_t idx, type *buffer, type data) \
{                                                             \
    buffer[idx] = data;                                       \
}
c concatenation c-preprocessor c99
3个回答
0
投票

执行此操作的常规方法是使用

stdint.h
中的类型,它们中没有空格。
uint32_t
int16_t
.

等名称

如果您想合并

struct Foo
enum Foo
,这仍然很困难,但这是一个很好的起点。

#include <stdio.h>
#include <stdint.h>

#define MAKE_FUNC(func_name, ret_type)                        \
ret_type##_t func_name##_##ret_type( void* alpha, int beta ) { \
    ret_type##_t ret_value;                                     \
    return ret_value; }

MAKE_FUNC(test, uint32) // Declares test_uint32 with return type uint32_t
MAKE_FUNC(test, int16)  // Declares test_int16 with return type int16_t

int main(void) {
    test_uint32( NULL, 0 );
    test_int16( NULL, 0 );
    return 0;
}

但是,您应该仔细研究 C11 中的 _Generic 表达式(在 C99 中不可用),因为它可能是您想要的最接近的匹配项。


-1
投票

为什么不只是:

#define gen_foo(_type) \
        static inline void foo_##_type (void) { /* Do whatever */ } 

gen_foo(int)
gen_foo(longint)
gen_foo(unsigned)
gen_foo(size_t)
gen_foo(longlongint)

-1
投票

明确说明:使用单独的类型名称和类型规范。

#define DEFINE_FUNCTION(type, name)                               \
    void Buffer_##name##_Add(size_t idx, type *buffer, type data) \

C 对于任何类型的通用编码的工具集都非常有限,特别是如果您使用的是 C99。最好避免任何诡计,即使这可能意味着更多的打字。

© www.soinside.com 2019 - 2024. All rights reserved.