【问题标题】:C: macro produced warning "statement with no effect"C:宏产生警告“声明无效”
【发布时间】:2015-04-10 15:24:22
【问题描述】:

我在 C 中有以下代码:

int do_something(void);

#ifdef SOMETHING
#define DO_SOMETHING() do_something()
#else
#define DO_SOMETHING() 0
#endif

在未定义 SOMETHING 的情况下编译时,此代码会产生警告“声明无效”。我正在尝试修复它,但有一个问题 - 使用此宏的代码有时会检查“返回值”,有时会忽略它。因此,我无法使用最简单的解决方案 - 在宏本身中强制转换为 void。

是否可以编写允许比较“返回值”并且在忽略时不产生此警告的宏?

我使用 gcc 来编译我的代码。

【问题讨论】:

  • 什么都不做的经典方法是#define DO_SOMETHING() ((void)0)。演员表停止编译器抱怨“无效的声明”。但是,如果您实际上有时会使用结果(因为do_something() 返回int,所以您应该使用该结果),那么它的帮助不如虚拟函数。另请参阅C #define macro for debug printing。

标签: c gcc macros warnings


【解决方案1】:

三种可能的解决方案:

定义一个 do_nothing 函数,它会被 gcc 优化出来:

int do_something(void);
int do_nothing(void) { return 0; } 

#ifdef SOMETHING
#define DO_SOMETHING() do_something()
#else
#define DO_SOMETHING() do_nothing()
#endif

或者,修改 do_something 实现以将 #ifdef 检查移到那里

int do_something(void)
{
  #ifndef SOMETHING
  return 0;
  #endif

// Your implementation here
}

您也可以使用#pragma 指令ignore the warning。

顺便问一下,你正在编译哪个版本的 gcc 以及使用哪些标志? gcc -Wall -pedantic 使用 GCC 4.9 不会产生警告。

【讨论】:

  • 啊,我忘了我可以使用另一个总是返回零的函数。谢谢!。我使用 gcc 4.4.7,它使用 -Wall 或 -Wunused-value 产生此警告。
  • 我会定义static inline int do_nothing() { return 0; };
【解决方案2】:
#include <stdio.h>

int do_something(void);

#ifdef SOMETHING
#define DO_SOMETHING() do_something()
#define DO_SOMETHING_ASSIGN() do_something()
#else
#define DO_SOMETHING() 
#define DO_SOMETHING_ASSIGN() 0
#endif

int do_something(void)
{
    static int cnt=0;
    /* code for do something here */
    ++cnt;
    printf("do_something has been called %d %s!\n",cnt,
        (cnt==1)?"time":"times");   
    return cnt;
}

void main(void)
{
    int x;

    DO_SOMETHING();

    x=DO_SOMETHING_ASSIGN();    

    printf("%d %d\n",x,DO_SOMETHING_ASSIGN());

    puts("end!!!");
}

希望对你有用!

如果你把这段代码保存为 main.c,你可以编译它:

gcc main.c -o main

当你运行 main 时,你会得到以下输出:

0 0
end!!!

如果你编译它:

gcc main.c -DSOMETHING -o main

当你运行 main 时,你会得到如下输出:

do_something has been called 1 time!
do_something has been called 2 times!
do_something has been called 3 times!
2 3
end!!!

【讨论】:

  • 这有一个问题——我必须修改我庞大的代码库。我需要可以在一个文件中应用的东西。
  • 我想你想使用/不要使用返回值的函数!我认为您在代码中使用了宏 DO_SOMETHING(),但这可以直接调用(不分配结果)或分配它的返回值。如果这是问题,更好的方法可能是按照 gjulianm 的指示修改函数 do_something。
  • int do_something(void) { #ifndef SOMETHING return 0; #else // 你的实现在这里 } #endif
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多