Следующий код работает как задумано,
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define GEN__INTEGER_ 0
#define GEN__STRING_ 1
#define GEN__U8_ARRAY_ 2
#define GEN__U16_ARRAY_ 3
#define GEN__U32_ARRAY_ 4
#define INTEGER_EQUAL(observed,expected) (observed == expected)
#define STRING_EQUAL(observed,expected) (strcmp((char *)observed, (char *)expected) == 0)
#define U8_ARRAY_EQUAL(observed,expected) (memcmp((uint8_t *)observed, (uint8_t *)expected, sizeof(expected)/sizeof(uint8_t)) == 0)
#define U16_ARRAY_EQUAL(observed,expected) (memcmp((uint16_t *)observed, (uint16_t *)expected, sizeof(expected)/sizeof(uint16_t)) == 0)
#define U32_ARRAY_EQUAL(observed,expected) (memcmp((uint32_t *)observed, (uint32_t *)expected, sizeof(expected)/sizeof(uint32_t)) == 0)
#define GENERIC_EQUAL(observed,expected) do{ \
printf("Is "#observed" equal to "#expected" ? "); \
if( _Generic( \
(observed)+0, \
default: INTEGER_EQUAL(observed,expected), \
char *: STRING_EQUAL(observed,expected), \
uint8_t *: U8_ARRAY_EQUAL(observed,expected), \
uint16_t *: U16_ARRAY_EQUAL(observed,expected), \
uint32_t *: U32_ARRAY_EQUAL(observed,expected) \
)) {printf("[OK]\n");} else {printf("[FAILS]\n");}\
}while(0)
#define INTEGER_PRINT(data) printf("integer : %d\n",data)
#define STRING_PRINT(data) printf("string : %s\n",data);
#define U8_ARRAY_PRINT(data) do{ \
uint8_t gen_buf_[sizeof(data)]; \
memcpy(gen_buf_,(uint8_t*)data,sizeof(data)); \
printf("arr_u8 : "); \
for(uint8_t _igen_ = 0; _igen_<sizeof(data)/sizeof(uint8_t);_igen_++) \
{ \
printf("%d,",gen_buf_[_igen_]); \
} \
printf("\n"); \
}while(0)
#define GENERIC_PRINT(data) do{\
switch(_Generic( \
(data)+0, \
default: GEN__INTEGER_, \
char *: GEN__STRING_, \
uint8_t *: GEN__U8_ARRAY_, \
uint16_t *: GEN__U16_ARRAY_, \
uint32_t *: GEN__U32_ARRAY_ \
)){ \
case GEN__STRING_: STRING_PRINT(data); break;\
case GEN__U8_ARRAY_: U8_ARRAY_PRINT(data); break;\
case GEN__U16_ARRAY_: U8_ARRAY_PRINT(data); break; \
case GEN__U32_ARRAY_: U8_ARRAY_PRINT(data); break; \
default: INTEGER_PRINT(data); break; \
} \
} while(0)
int main()
{
uint8_t integ1 = 0;
uint8_t integ2 = 1;
GENERIC_EQUAL(integ1,integ2);
GENERIC_PRINT(integ1);
char string1[]="abc";
char string2[]="abc";
GENERIC_EQUAL(string1,string2);
GENERIC_PRINT(string1);
uint8_t array0[]={1,2};
uint8_t array1[]={1,2};
uint8_t array2[]={1,3};
uint8_t array3[]={1,2,3,4};
GENERIC_EQUAL(array1,array0);
GENERIC_EQUAL(array1,array2);
GENERIC_EQUAL(array1,array3);
GENERIC_PRINT(array1);
GENERIC_PRINT(array2);
GENERIC_PRINT(array3);
return 0;
}
, но выдает следующие предупреждения:
main.c:16:78: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
main.c:25:63: note: in expansion of macro ‘U8_ARRAY_EQUAL’
main.c:69:5: note: in expansion of macro ‘GENERIC_EQUAL’
main.c:17:57: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
[...]
main.c:81:5: note: in expansion of macro ‘GENERIC_PRINT’
main.c:35:53: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
[...]
main.c:31:40: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘uint8_t * {aka unsigned char *}’ [
-Wformat=]
main.c:70:50: note: in expansion of macro ‘INTEGER_PRINT’
main.c:97:5: note: in expansion of macro ‘GENERIC_PRINT’
Есть ли способ избежать первых предупреждений [-Wint-to-pointer -cast]?
Я не могу звонить без каста ...