3

I have following code in C:

int do_something(void);

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

This code produced warning "statement with no effect" when compiled without SOMETHING defined. I am trying to fix it, but there is one problem - code which uses this macro sometimes checks that "return value" and sometimes ignores it. Because of this I cannot use the easiest solution - casting to void in macro itself.

Is it possible to write macro which allows to compare "returned value" and does not produce this warning when it is ignored?

I use gcc to compile my code.

Daniel Frużyński
  • 2,091
  • 19
  • 28
  • 2
    The classic way to do nothing is `#define DO_SOMETHING() ((void)0)`. The cast stops the compiler complaining about 'statement with no effect'. However, if you actually sometimes use the result (which you should since `do_something()` returns an `int`), then that doesn't help as much as a dummy function. See also [C `#define` macro for debug printing](http://stackoverflow.com/questions/1644868/). – Jonathan Leffler Apr 10 '15 at 17:42

2 Answers2

2

Three possible solutions:

Define a do_nothing function, which will get optimized out by 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

Or, modify the do_something implementation to move the #ifdef check there

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

// Your implementation here
}

You can also ignore the warning using #pragma directives.

By the way, which version of gcc and with which flags are you compiling? gcc -Wall -pedantic with GCC 4.9 doesn't produce the warning.

gjulianm
  • 834
  • 7
  • 22
0
#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!!!");
}

I hope this is usefull to you!

If you save this code as main.c, you may compile it with:

gcc main.c -o main

when you run main, you obtain the following output:

0 0
end!!!

If you compile it with:

gcc main.c -DSOMETHING -o main

When you run main, you obtain the following output:

do_something has been called 1 time!
do_something has been called 2 times!
do_something has been called 3 times!
2 3
end!!!
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Sir Jo Black
  • 2,024
  • 2
  • 15
  • 22
  • There is one problem with this - I would have to modify my huge code base. I need something what can be applied in one file. – Daniel Frużyński Apr 10 '15 at 17:00
  • I image that you want use/don't use a function that returns a value! I think you use in your code the macro DO_SOMETHING(), but this may be called directly (without assigning the result) or assigning it's returned value. If this is the problem the better way might be to modify the function do_something as gjulianm indicates. – Sir Jo Black Apr 10 '15 at 17:30
  • int do_something(void) { #ifndef SOMETHING return 0; #else // Your implementation here } #endif – Sir Jo Black Apr 10 '15 at 17:31