如何为条件代码修复宏#ifdef?

时间:2019-07-17 11:35:48

标签: c macros

我有方法

int someMethod(int arg1, int arg2)
{
  //method body
}

并且我为同一方法定义了一个宏_MACRO,以便根据条件执行该宏。

#ifdef _MACRO
int someMethod(int arg1, int agr2)
{
  //method body
}
#endif

我在说someMethod时使用了someAnotherMethod(int arg1, int arg2)

int someAnotherMethod(int arg1, int arg2)
{
  //othercode
  #ifdef __MACRO
  someMethod(int arg1, int agr2);
  //othercode
}

在someAnotherMethod()中,我得到了同样的错误。

error C4100: 'arg1' : unreferenced formal parameter

谁能解释这个问题并提供替代方法?

4 个答案:

答案 0 :(得分:3)

由于某些编译器标志,您收到的错误已从警告中升高。您会收到警告,因为未定义__MACRO时,您的someAnotherMethod函数具有未使用的参数。

使该警告消失的常规方法是将参数强制转换为void,然后使用它。

否则,您的宏名称无效,您不能使用双下划线或前导下划线后跟大写字母。此符号保留给C实现。

相反,使用YOUR_LIBRARY_NAME_MACRO作为命名约定。

int someAnotherMethod(int arg1, int arg2) {
# ifdef LIB_MACRO
  someMethod(int arg1, int agr2);
# else
  (void) arg1;
  (void) arg2;
# endif
}

这有时隐藏在宏后面:

#define UNUSED(x) (void) (x)

…

int someAnotherMethod(int arg1, int arg2) {
  …
  UNUSED(arg1);
  …
}

答案 1 :(得分:1)

我很犹豫向您提供此解决方案,因为这是有史以来最丑的骇客。

上下文:我正在使用一个非常老的C编译器,它有很多怪癖,其中之一是有关未使用的参数或变量的警告可能会在优化过程的任何给定步骤中发生。因此,例如,有时您会收到警告,指出某个变量尚未使用,但实际上,它已经被优化了。

#ifdef也使旧代码库杂乱无章,因此我不止一次遇到您的问题。

黑客

suppresswarning.h

extern long SuppressWarning;
#define SUPPRESS_WARNING(p) (SuppressWarning += (uintptr_t)&(p))

suppresswarning.c

long SupressWarning;

YourFile.c

#include "suppresswarning.h"

int someAnotherMethod(int arg1, int arg2)
{
  //othercode
#ifdef __MACRO
  someMethod(arg1, agr2);
  //othercode
#else
  SUPPRESS_WARNING(arg1);
  SUPPRESS_WARNING(arg2);
#endif
}

SUPPRESS_WARNING宏本质上阻止了编译器优化变量。这对于任何阅读该代码的新程序员来说都是显而易见的附加值; SUPPRESS_WARNING禁止显示警告。

此技巧不一定需要添加翻译单元。大多数项目都有用于调试或实用功能的其他单元;可以放在那里。

答案 2 :(得分:0)

替代:

#define FOO (FOO1)

enum Foo {
        FOO1,
        FOO2,
        FOO3
};

int foo1(void);
int foo2(void);
int foo3(void);

int foo(void)
{

        switch (FOO) {
        case FOO1:
                return foo1();
        case FOO2:
                return foo2();
        case FOO3:
                return foo3();
        default:
                return -1;
        }
}

int foo1(void)
{
        return 1;
}

int foo2(void)
{
        return 2;
}

int foo3(void)
{
        return 3;
}

这样做的好处是编译器会编译所有代码,因此您可以检查代码中是否存在任何错误,而使用预处理器则不会。

基本上,预处理器#if和company仅在使用可能不可用的功能时有用,但如果有可用功能,则首选ifswitch

答案 3 :(得分:0)

int someAnotherMethod(
#ifdef __XYZ
int arg1,
 #else
int,
#endif
int arg2)
{
//othercode
#ifdef __XYZ
someMethod(int arg1, int agr2);
#endif
//othercode
}

这对两个参数都很好。