如何避免在多态打印宏中使用 #if

Gui*_*e D 0 c macros if-statement

让我们尝试运行以下代码:

#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;
}

Run Code Online (Sandbox Code Playgroud)

它返回错误:

main.c: In function ‘main’:
main.c:12:39: error: subscripted value is neither array nor pointer nor vector
                         printf("%d", y[0]); \
Run Code Online (Sandbox Code Playgroud)

好的,所以我们需要一个 #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;
}
Run Code Online (Sandbox Code Playgroud)

但它返回:

main.c:11:28: error: '#' is not followed by a macro parameter
 #define MY_MACRO2(isArray,y) do { \
Run Code Online (Sandbox Code Playgroud)

无论如何要在宏中调用#if 语句吗?如果没有,我怎么能做这样的事情?

注意:我使用的是 IAR 8.20.2

(此链接没有帮助)

我想知道为什么我不想使用 2 个不同的宏是因为我需要这样的东西(伪代码):

myFunction(int or array):
   doSomethingWhereIntAndArrayBehavesDifferentlyLikePrintf();
   doSomethingelse();
   doSomethingelse();
   doSomethingWhereIntAndArrayBehavesDifferentlyLikePrintf();
   doSomethingelse();
Run Code Online (Sandbox Code Playgroud)
  • 它非常方便:您可以分解代码。
  • 这是实现多态的一种方式。
  • 它模仿 C++ 模板功能。

Lun*_*din 5

无论如何要在宏中调用#if 语句吗?

不可能。

如果没有,我怎么能做这样的事情?

您可以使用 C11 _Generic:

#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;
}
Run Code Online (Sandbox Code Playgroud)