0

In this example code a macro is either defined or commented out by the programmer in order to remove a function from the released software.

#include <stdio.h>

#define MACRO //or omitted

#ifdef MACRO
    void Function(const char* str)
    {
        printf("%s\n", str);
    }

#else
    #define Function(str)

#endif

int main(void)
{
    Function("hello world");
    getchar();
    return 0;
}

Is there anything wrong with this?

Lucy Seal
  • 3
  • 4
  • It will work. Editing the file so you can define or undefine MACRO isn't so hot, but there are ways around that. – Jonathan Leffler May 06 '17 at 21:12
  • If you end up with tons of code, it can make it harder/less pleasant to try and read, and depending on the tools you're using it could make it a pain in the ass to debug, depending on whether or not you can see which code has been compiled out code at runtime. – George May 06 '17 at 21:14
  • It was actually intended for printing out error messages and or writing them into a text file. But I wanted to remove that in the released version. – Lucy Seal May 06 '17 at 21:17
  • If you want a debug-only macro, then see [C `#define` macro for debug printing](http://stackoverflow.com/questions/1644868/). – Jonathan Leffler May 06 '17 at 21:28

2 Answers2

1

Even though your solution works, I prefer the following approach:

#include <stdio.h>

#define MACRO //or omitted

#ifdef MACRO
#define FUNCTION(a) Function(a);
#else
#define FUNCTION(a)
#endif

#ifdef MACRO
    void Function(const char* str)
    {
        printf("%s\n", str);
    }
#endif

int main(void)
{
    FUNCTION("hello world")
    getchar();
    return 0;
}

Note: FUNCTION is the macro, Function is the actual name of the function

This works by defining the macro FUNCTION(a) to a call to Function(const char*) when MACRO is enabled. On the other hand, when MACRO is disabled, calls to FUNCTION(a) will be defined to nothing.

I tend to prefer this method since it would be easier to abstract away the macro used to define your call from the macro defining your function definition. You might have cases where in release mode you only need to remove some of the calls to Function. In that case the definition of Function() is still required. For example:

#include <stdio.h>

#define DEBUG //or omitted

#ifdef DEBUG
#define FUNCTION(a) Function(a);
#else
#define FUNCTION(a)
#endif

void Function(const char* str)
{
    printf("%s\n", str);
}

int main(void)
{
    // Call function with Hello World only in debug
    FUNCTION("hello world")
    getchar();

    // Call function with goodbye world in both debug and release
    Function("goodbye world");
    return 0;
}
Brian Zammit
  • 179
  • 6
0

It will work. But the entire symbol is removed this way. I prefer the following method.

#include <stdio.h>

#define MACRO    1

#if MACRO
    void Function(const char* str)
    {
        printf("%s\n", str);
    }

#else
    void Function(const char *str){}

#endif

int main(void)
{
    Function("hello world");
    getchar();
    return 0;
}

The following has changed:

  • The #if now compares a boolean. Your IDE is now able to find where MACRO is defined, in all cases. (right click, find definition)
  • You can, by changing MACRO to 2, change the entire meaning of Function. For example, a release compiled variant might contain a print to file or system log.
  • There will always be a symbol for Function, even if it does nothing, even in compiled code. This has the benefit that the string literals in the argument still count to the size statistics. As an embedded developer, I find this important.

Obviously, this is partly the preference of the one who crafts the code.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jeroen3
  • 919
  • 5
  • 20
  • You might use `#ifndef MACRO` / `#define MACRO 1` / `#endif` so that the programmer can override the default setting on the compiler command line with `-DMACRO=0`, without needing to edit the source code. Also, changing MACRO to 2 would not change things — setting it to 0 would. Your dummy function would generate compilation warnings about unused arguments under my default compilation options; fixing that isn't as easy as you'd like. – Jonathan Leffler May 06 '17 at 21:30