My TLV structure can hold string or integer. I'm trying to create a macro that handles them both.
The example below runs as expected, but it compiles with warnings from the MACRO expansion. I understand the precompiler cannot know what type of value I'm going to assign at runtime, which is why I think it's raising the warning.
How can this little code snippet be fixed so it generates no compile warnings?
FWIW, I can code around this by not using the MACRO, but would prefer to use it if possible.
$ gcc -o simple{,.c} && ./simple
simple.c: In function ‘main’:
simple.c:25:21: warning: assignment makes pointer from integer without a cast [enabled by default]
tlv.value_str = (val); \
^
simple.c:38:3: note: in expansion of macro ‘TLV2STR_MACRO’
TLV2STR_MACRO(string, TYPE_INT, 11);
^
simple.c:28:21: warning: assignment makes integer from pointer without a cast [enabled by default]
tlv.value_int = (val); \
^
simple.c:41:3: note: in expansion of macro ‘TLV2STR_MACRO’
TLV2STR_MACRO(string, TYPE_STRING, "ELEVEN");
^
-----------------------------
INT : 11
STRING: ELEVEN
-----------------------------
#include <stdio.h>
typedef struct _tlv_s {
int type;
size_t length;
union _value {
int value_int;
char *value_str;
} value_u;
} tlv_t;
#define value_int value_u.value_int
#define value_str value_u.value_str
#define TYPE_STRING 0
#define TYPE_INT 1
#define TLV2STR_MACRO(s, t, val) { \
tlv_t tlv; \
tlv.type = (t); \
if (t == TYPE_STRING) { \
tlv.value_str = (val); \
sprintf(s, "STRING: %s", tlv.value_str); \
} else { \
tlv.value_int = (val); \
sprintf(s, "INT : %d", tlv.value_int); \
} \
}
int main(int argc, char *argv[])
{
char string[128];
printf("-----------------------------\n");
TLV2STR_MACRO(string, TYPE_INT, 11);
printf("%s\n", string);
TLV2STR_MACRO(string, TYPE_STRING, "ELEVEN");
printf("%s\n", string);
printf("-----------------------------\n");
}