Search code examples
cconcatenationc-preprocessorc99

Concatenate preprocessor tokens


How to write a macro #define CONCATENATE(x) that will produce the following results:

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

The result can be different than what I've written above. The only requirement is that the result is a single token. I need it to be a single token because this token will be used to define a function with name containing this token, for example void Foo_longlongint(void);

EDIT

I want to create generic functions using some macro trickery. For example lets say we want to declare a generic buffer:

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

Now I want to create functions for many possible types, for example:

#define DEFINE_FUNCTION(type)                                 \
void Buffer_##type##_Add(size_t idx, type *buffer, type data) \
{                                                             \
    buffer[idx] = data;                                       \
}

Solution

  • The conventional way to do this is to use the types from stdint.h, which do not have whitespace in them. Names such as uint32_t and int16_t.

    This will still be difficult if you want to incorporate struct Foo and enum Foo, but its a good starting point.

    #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;
    }
    

    However, you should really look into the _Generic expression in C11 (not available in C99) as that is probably the closest match to what you want.