C 如何避免在多态打印宏中使用#if
让我们尝试运行以下代码:C 如何避免在多态打印宏中使用#if,c,if-statement,macros,C,If Statement,Macros,让我们尝试运行以下代码: #include <stdio.h> #define MY_MACRO1(isArray,y) do { \ if(isArray) \ printf("%d", y[0]); \ else \ printf("%d", y); \ }
#include <stdio.h>
#define MY_MACRO1(isArray,y) do { \
if(isArray) \
printf("%d", y[0]); \
else \
printf("%d", y); \
}while(0)
int main()
{
int a = 38;
int b[]={42};
MY_MACRO1(0,a);
return 0;
}
好的,因此我们需要一个#if语句,仅当变量是数组时才运行y[0]:
#define MY_MACRO2(isArray,y) do { \
#if isArray \
printf("%d", y[0]); \
#else \
printf("%d", y); \
#endif \
}while(0)
int main()
{
int a = 38;
int b[]={42};
MY_MACRO2(0,a);
return 0;
}
但它的回报是:
main.c:11:28: error: '#' is not followed by a macro parameter
#define MY_MACRO2(isArray,y) do { \
宏中是否有调用#if语句的方法?
如果没有,我怎么能做这样的事
注意:我使用的是IAR 8.20.2
(这没有帮助)
我想知道为什么我不想使用2个不同的宏,因为我需要这样做(伪代码):
- 它非常方便:您可以分解代码
- 这是一种实现多态性的方法 它模仿C++模板特征。
#包括
#定义MY_MACRO1(isArray,y)printf(“%d”,BOOST_PP_IF(isArray,(y)[0],(y)))
首先让我说,我认为您不应该为此使用宏。您应该有两个单独的函数,可能还有额外的
\u Generic
表达式,如Lundins答案所示
但是,可以使用多个宏定义:
#define MY_MACRO(isArray,y) MY_MACRO_ ## isArray (y)
#define MY_MACRO_0(y) printf("%d", y)
#define MY_MACRO_1(y) printf("%d", y[0])
宏中是否有调用#if语句的方法
不可能
如果没有,我怎么能做这样的事
您可以使用C11\u泛型:
#include <stdio.h>
void int_func (int obj)
{
printf("%d\n", obj);
}
void int_arr_func (const int* obj)
{
printf("%d\n", obj[0]);
}
void float_func (float obj)
{
printf("%f\n", obj);
}
#define MY_MACRO2(y) _Generic((y), \
int: int_func, \
int*: int_arr_func, \
float: float_func ) (y)
int main (void)
{
int a = 38;
int b[]={42};
float pi = 3.14f;
MY_MACRO2(a);
MY_MACRO2(b);
MY_MACRO2(pi);
return 0;
}
#包括
void int_func(int obj)
{
printf(“%d\n”,obj);
}
void int_arr_func(常量int*obj)
{
printf(“%d\n”,obj[0]);
}
无效浮点函数(浮点对象)
{
printf(“%f\n”,obj);
}
#定义MY_MACRO2(y)_Generic((y)\
int:int_func\
int*:int_arr_func\
浮动:浮动函数(y)
内部主(空)
{
INTA=38;
int b[]={42};
浮点数pi=3.14f;
MY_MACRO2(a);
MY_MACRO2(b);
MY_MACRO2(pi);
返回0;
}
总结一下,另一种方法是使用VLA和宏
使用泛型
#包括
#包括
#包括
#包括
#包括
静态内嵌无效打印阵列(uint32\u t obj)
{
printf(“集成>>uint32\u t:%u\n”,obj);
}
静态内嵌无效打印阵列(uint16\u t obj)
{
printf(“INTEGER>>uint16\u t:%u\n”,obj);
}
静态内嵌无效打印阵列(uint8\u t obj)
{
printf(“集成>>uint8\u t:%d\n”,obj);
}
静态内联void打印数组_u32(常量uint32_t*obj)
{
printf(“数组>>uint32_t:”);
对于(uint32\u t i=0;i uint32\u t:257>>确定
MY_多态打印2(i2);//集成>uint16\u t:257>>确定
MY_多态打印2(i3);//集成>uint8\u t:25>>确定
MY_多态打印2(a1);//数组>>uint32\u t:42-43->失败
MY_多态打印2(a2);//数组>>uint16\u t:22-23-24-257->确定
MY_POLYMORPHIC_PRINT2(a3);//数组>>uint8\u t:12-13-14-25-253-127-0-0->>失败
返回0;
}
优点:
- 简单宏+简单函数
- 你不再需要“isArray”了
- 你不需要#如果
- 类型安全
- 如何获取数组大小?-->在没有
- 限于C11
#包括
#包括
#包括
#包括
#包括
#定义MY_多态性_PRINT1(y,type)do{\
如果((sizeof(y)/sizeof(type)!=1)和&(sizeof(y)/sizeof(type)!=sizeof(y)))\
{ \
阵列缓冲类型[sizeof(y)/sizeof(类型)]\
memcpy(&arrayBuffer,&y,sizeof(y))\
printf(“数组>>”#类型):\
对于(uint32\u t i=0;i>uint32\u t:257>>正常
MY_多态打印1(i2,uint16\u t);//整数>>uint16\u t:257>>确定
MY_多态打印1(i3,uint8\u t);//整数>>uint8\u t:25>>确定
MY_POLYMORPHIC_PRINT1(i1,uint8_t);//整数>>uint8_t:1>>键入错误,强制转换正在工作
MY_polymogic_PRINT1(a1,uint32_t);//数组>>uint32_t:42-43-44-257->正常
MY_POLYMORPHIC_PRINT1(a2,uint16_t);//数组>>uint16_t:22-23-24-257->正常
MY_多态打印1(a3,uint8\u t);//整数>>uint8\u t:12>>失败
MY_POLYMORPHIC_PRINT1(a1,uint16_t);//integer>>uint16_t:42-0-43-0-44-0-257-0->类型错误,强制转换在某种程度上起作用
返回0;
}
优点:
- 灵活的
- 兼容性:C99、C11
#include <boost/preprocessor/if.hpp> #define MY_MACRO1(isArray,y) printf("%d", BOOST_PP_IF(isArray, (y)[0], (y)))
#define MY_MACRO(isArray,y) MY_MACRO_ ## isArray (y) #define MY_MACRO_0(y) printf("%d", y) #define MY_MACRO_1(y) printf("%d", y[0])
#include <stdio.h> void int_func (int obj) { printf("%d\n", obj); } void int_arr_func (const int* obj) { printf("%d\n", obj[0]); } void float_func (float obj) { printf("%f\n", obj); } #define MY_MACRO2(y) _Generic((y), \ int: int_func, \ int*: int_arr_func, \ float: float_func ) (y) int main (void) { int a = 38; int b[]={42}; float pi = 3.14f; MY_MACRO2(a); MY_MACRO2(b); MY_MACRO2(pi); return 0; }
#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> static inline void printNonArray_u32 (uint32_t obj) { printf("interger >> uint32_t : %u\n",obj); } static inline void printNonArray_u16 (uint16_t obj) { printf("interger >> uint16_t : %u\n",obj); } static inline void printNonArray_u8 (uint8_t obj) { printf("interger >> uint8_t : %d\n",obj); } static inline void printArray_u32 (const uint32_t* obj) { printf("array >> uint32_t : "); for(uint32_t i = 0 ; i<sizeof(obj)/sizeof(uint32_t) ; i++ ) printf("%d - ",(uint32_t)obj[i]); printf("\n"); } static inline void printArray_u16 (const uint16_t* obj) { printf("array >> uint16_t : "); for(uint32_t i = 0 ; i<sizeof(obj)/sizeof(uint16_t) ; i++ ) printf("%d - ",(uint16_t)obj[i]); printf("\n"); } static inline void printArray_u8(const uint8_t* obj) { printf("array >> uint8_t : "); for(uint32_t i = 0 ; i<sizeof(obj)/sizeof(uint8_t) ; i++ ) printf("%d - ",(uint8_t)obj[i]); printf("\n"); } #define MY_POLYMORPHIC_PRINT2(y) _Generic((y), \ uint32_t: printNonArray_u32, \ uint32_t*: printArray_u32, \ uint16_t: printNonArray_u16, \ uint16_t*: printArray_u16, \ uint8_t: printNonArray_u8, \ uint8_t*: printArray_u8 ) (y) int main() { uint32_t i1 = 257; uint16_t i2 = 257; uint8_t i3 = 25; uint32_t a1[]={42,43,44,257}; uint16_t a2[]={22,23,24,257}; uint8_t a3[]={12,13,14,25}; printf("MY_POLYMORPHIC_PRINT2 - _Generic\n"); MY_POLYMORPHIC_PRINT2(i1); //interger >> uint32_t : 257 >> OK MY_POLYMORPHIC_PRINT2(i2); //interger >> uint16_t : 257 >> OK MY_POLYMORPHIC_PRINT2(i3); //interger >> uint8_t : 25 >> OK MY_POLYMORPHIC_PRINT2(a1); //array >> uint32_t : 42 - 43 - >> FAILS MY_POLYMORPHIC_PRINT2(a2); //array >> uint16_t : 22 - 23 - 24 - 257 - >> OK MY_POLYMORPHIC_PRINT2(a3); //array >> uint8_t : 12 - 13 - 14 - 25 - 253 - 127 - 0 - 0 - >> FAILS return 0; }
#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define MY_POLYMORPHIC_PRINT1(y, type) do { \ if((sizeof(y)/sizeof(type) != 1) && (sizeof(y)/sizeof(type) != sizeof(y))) \ { \ type arrayBuffer[sizeof(y)/sizeof(type)]; \ memcpy(&arrayBuffer,&y,sizeof(y)); \ printf("array >> "#type" : "); \ for(uint32_t i = 0 ; i<sizeof(y)/sizeof(type) ; i++ ) \ printf("%d - ",arrayBuffer[i]); \ printf("\n"); \ } \ else \ { \ type intBuffer = (type)*((type*)(&y)); \ printf("integer >> "#type" : %d\n",intBuffer); \ } \ }while(0) int main() { uint32_t i1 = 257; uint16_t i2 = 257; uint8_t i3 = 25; uint32_t a1[]={42,43,44,257}; uint16_t a2[]={22,23,24,257}; uint8_t a3[]={12,13,14,25}; printf("MY_POLYMORPHIC_PRINT1 - VLA\n"); MY_POLYMORPHIC_PRINT1(i1,uint32_t);// integer >> uint32_t : 257 >> OK MY_POLYMORPHIC_PRINT1(i2,uint16_t);// integer >> uint16_t : 257 >> OK MY_POLYMORPHIC_PRINT1(i3,uint8_t); // integer >> uint8_t : 25 >> OK MY_POLYMORPHIC_PRINT1(i1,uint8_t); // integer >> uint8_t : 1 >> POK wrong type, casting is working MY_POLYMORPHIC_PRINT1(a1,uint32_t);// array >> uint32_t : 42 - 43 - 44 - 257 - >> OK MY_POLYMORPHIC_PRINT1(a2,uint16_t);// array >> uint16_t : 22 - 23 - 24 - 257 - >> OK MY_POLYMORPHIC_PRINT1(a3,uint8_t); // integer >> uint8_t : 12 >> FAILS MY_POLYMORPHIC_PRINT1(a1,uint16_t); // integer >> uint16_t : 42 - 0 - 43 - 0 - 44 - 0 - 257 - 0 - >> POK wrong type, casting is somewhat working return 0; }
#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define MY_VLA_PRINT_ARRAY(y, type) do{\ type arrayBuffer[sizeof(y)/sizeof(type)]; \ memcpy(&arrayBuffer,&y,sizeof(y)); \ printf("array >> "#type" : "); \ for(uint32_t i = 0 ; i<sizeof(y)/sizeof(type) ; i++ ) \ printf("%d - ",arrayBuffer[i]); \ printf("\n"); \ }while(0) #define MY_VLA_PRINT_NOT_ARRAY(y, type) do{\ type intBuffer = (type)*((type*)(&y)); \ printf("integer >> "#type" : %d\n",intBuffer); \ }while(0) #define MY_POLYMORPHIC_PRINT3( y, isArray, type) do { \ MY_VLA_PRINT_ ## isArray (y, type); \ }while(0) int main() { uint32_t i1 = 257; uint16_t i2 = 257; uint8_t i3 = 25; uint32_t a1[]={42,43,44,257}; uint16_t a2[]={22,23,24,257}; uint8_t a3[]={12,13,14,25}; printf("MY_POLYMORPHIC_PRINT3 - ## + VLA\n"); MY_POLYMORPHIC_PRINT3(i1,NOT_ARRAY,uint32_t); // integer >> uint32_t : 257 >> OK MY_POLYMORPHIC_PRINT3(i2,NOT_ARRAY,uint16_t); // integer >> uint16_t : 257 >> OK MY_POLYMORPHIC_PRINT3(i3,NOT_ARRAY,uint8_t); // integer >> uint8_t : 25 >> OK MY_POLYMORPHIC_PRINT3(i1,NOT_ARRAY,uint8_t); // integer >> uint8_t : 1 >> POK wrong type, casting is working MY_POLYMORPHIC_PRINT3(i1,ARRAY,uint8_t); // array >> uint8_t : 1 - 1 - 0 - 0 - >> POK (does not crash) MY_POLYMORPHIC_PRINT3(a1,ARRAY,uint32_t); // array >> uint32_t : 42 - 43 - 44 - 257 - >> OK MY_POLYMORPHIC_PRINT3(a2,ARRAY,uint16_t); // array >> uint16_t : 22 - 23 - 24 - 257 - >> OK MY_POLYMORPHIC_PRINT3(a3,ARRAY,uint8_t); // array >> uint8_t : 12 - 13 - 14 - 25 - >> OK MY_POLYMORPHIC_PRINT3(a1,ARRAY,uint16_t); // array >> uint16_t : 42 - 0 - 43 - 0 - 44 - 0 - 257 - 0 - >> POK wrong type, casting is somewhat working MY_POLYMORPHIC_PRINT3(a1,NOT_ARRAY,uint16_t); // integer >> uint16_t : 42 >> POK (does not crash) return 0; }
#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define MY_NON_VLA_PRINT_ARRAY_U32(y) do{\ printf("array >> uint32_t : "); \ for(uint32_t i = 0 ; i< sizeof(y) / sizeof(uint32_t) ; i++ ) \ printf("%d - ",(uint32_t)*((uint32_t*)&y+(uint32_t*)i)); \ printf("\n"); \ }while(0) #define MY_NON_VLA_PRINT_ARRAY_U16(y) do{\ printf("array >> uint16_t : "); \ for(uint32_t i = 0 ; i< sizeof(y) / sizeof(uint16_t) ; i++ ) \ printf("%d - ",(uint16_t)*((uint16_t*)&y+(uint16_t*)i)); \ printf("\n"); \ }while(0) #define MY_NON_VLA_PRINT_ARRAY_U8(y) do{\ printf("array >> uint8_t : "); \ for(uint32_t i = 0 ; i< sizeof(y) / sizeof(uint8_t) ; i++ ) \ printf("%d - ",(uint8_t)*((uint8_t*)&y+(uint8_t*)i)); \ printf("\n"); \ }while(0) #define MY_NON_VLA_PRINT_NOT_ARRAY_U32(y) do{\ printf("integer >> uint32_t : %d\n",(uint32_t)y); \ }while(0) #define MY_NON_VLA_PRINT_NOT_ARRAY_U16(y) do{\ printf("integer >> uint16_t : %d\n",(uint16_t)y); \ }while(0) #define MY_NON_VLA_PRINT_NOT_ARRAY_U8(y) do{\ printf("integer >> uint8_t : %d\n",(uint8_t)y); \ }while(0) #define MY_POLYMORPHIC_PRINT4( y, isArray, type) do { \ MY_NON_VLA_PRINT_ ## isArray ## _ ## type (y); \ }while(0) int main() { uint32_t i1 = 257; uint16_t i2 = 257; uint8_t i3 = 25; uint32_t a1[]={42,43,44,257}; uint16_t a2[]={22,23,24,257}; uint8_t a3[]={12,13,14,25}; printf("MY_POLYMORPHIC_PRINT4 - ## + no VLA\n"); MY_POLYMORPHIC_PRINT4(i1,NOT_ARRAY,U32); MY_POLYMORPHIC_PRINT4(i2,NOT_ARRAY,U16); MY_POLYMORPHIC_PRINT4(i3,NOT_ARRAY,U8); MY_POLYMORPHIC_PRINT4(i1,NOT_ARRAY,U8); MY_POLYMORPHIC_PRINT4(i1,ARRAY,U8); MY_POLYMORPHIC_PRINT4(a1,ARRAY,U32); MY_POLYMORPHIC_PRINT4(a2,ARRAY,U16); MY_POLYMORPHIC_PRINT4(a3,ARRAY,U8); MY_POLYMORPHIC_PRINT4(a1,ARRAY,U16); MY_POLYMORPHIC_PRINT4(a1,NOT_ARRAY,U16); //does not compile: // error: invalid operands to binary + (have ‘uint32_t * {aka unsigned int *}’ and ‘uint32_t * {aka unsigned int *}’) // printf("%d - ",(uint32_t)*((uint32_t*)&y+(uint32_t*)i)); \ // error: invalid operands to binary + (have ‘uint16_t * {aka short unsigned int *}’ and ‘uint16_t * {aka short unsigned int *}’) // printf("%d - ",(uint16_t)*((uint16_t*)&y+(uint16_t*)i)); \ // error: invalid operands to binary + (have ‘uint8_t * {aka unsigned char *}’ and ‘uint8_t * {aka unsigned char *}’) // printf("%d - ",(uint8_t)*((uint8_t*)&y+(uint8_t*)i)); \ return 0; }