Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typechecking macro arguments in C

Tags:

c

macros

Is it possible to typecheck arguments to a #define macro? For example:

typedef enum
{
    REG16_A,
    REG16_B,
    REG16_C
}REG16;

#define read_16(reg16)  read_register_16u(reg16); \
                        assert(typeof(reg16)==typeof(REG16));

The above code doesn't seem to work. What am I doing wrong?

BTW, I am using gcc, and I can guarantee that I will always be using gcc in this project. The code does not need to be portable.

like image 580
Rocketmagnet Avatar asked Jan 17 '11 11:01

Rocketmagnet


People also ask

What is macro with arguments in C?

Function-like macros can take arguments, just like true functions. To define a macro that uses arguments, you insert parameters between the pair of parentheses in the macro definition that make the macro function-like. The parameters must be valid C identifiers, separated by commas and optionally whitespace.

How many arguments macro can have in C?

For portability, you should not have more than 31 parameters for a macro. The parameter list may end with an ellipsis (…).

Can we change macro value in C?

You can't. Macros are expanded by the Preprocessor, which happens even before the code is compiled. It is a purely textual replacement.

Can we pass arguments in macro?

A parameter can be either a simple string or a quoted string. It can be passed by using the standard method of putting variables into shared and profile pools (use VPUT in dialogs and VGET in initial macros).


1 Answers

gcc supports typeof

e.g. a typesafe min macro taken from the linux kernel

#define min(x,y) ({ \
    typeof(x) _x = (x); \
    typeof(y) _y = (y); \
    (void) (&_x == &_y);        \
    _x < _y ? _x : _y; })

but it doesn't allow you to compare two types. Note though the pointer comparison which Will generate a warning - you can do a typecheck like this (also from the linux kernel)

#define typecheck(type,x) \
({  type __dummy; \
    typeof(x) __dummy2; \
    (void)(&__dummy == &__dummy2); \
    1; \
})

Presumably you could do something similar - i.e. compare pointers to the arguments.

like image 151
Dipstick Avatar answered Sep 17 '22 13:09

Dipstick