Reputation: 9521
I have the following structure (simplified):
struct error_t{
const char *file;
const char *error_desc;
};
I wrote a macro to create the structure
#define ERROR_SET(error_desc) \
{ \
struct error_t tmp = {.error_desc = error_desc, .file = __FILE__}; \
struct error_t *ptr = malloc(sizeof(*ptr)); \
memcpy(ptr, &tmp, sizeof(tmp)); \
*error_ptr = ptr; \
}
The problem is that at the line
struct error_t tmp = {.error_desc = error_desc, .file = __FILE__}
both error_desc
s .error_desc = error_desc
are replaced which is not what I wanted. The only solution I can see is to rename the macro function parameter from error_desc
to _error_desc
, but maybe there is a better way. Maybe we can sort of "escape" the error_desc
to be substituted in the .error_desc
?
Upvotes: 0
Views: 149
Reputation: 67546
Just do not use the same name for the parameter and the struct member
Upvotes: 3
Reputation: 320491
You can "deceive" the preprocessor with something like
#define CONCAT(a, b) a##b
#define ERROR_SET(error_desc) \
{ \
struct error_t tmp = { .CONCAT(error,_desc) = error_desc, .file = __FILE__ }; \
...\
}
but it is just not worth it. Just rename the parameter. And develop a convention for parameter naming that would help you to avoid such naming conflicts in the future.
On the second thought, the extra CONCAT
macro is not even necessary. This will achieve the same objective
#define ERROR_SET(error_desc) \
{ \
struct error_t tmp = { .error##_desc = error_desc, .file = __FILE__ }; \
...\
}
Upvotes: 1
Reputation: 26800
You can have a different MACRO that the preprocessor would replace as error_desc
.
#define ERROR_DESC error_desc
Then you can define ERROR_SET
like this:
#define ERROR_SET(error_desc) \
{ \
struct error_t tmp = {.ERROR_DESC = error_desc, .file = __FILE__}; \
struct error_t *ptr = malloc(sizeof(*ptr)); \
memcpy(ptr, &tmp, sizeof(tmp)); \
*error_ptr = ptr; \
}
This works because the substitution is done only once.
Upvotes: 2