4

I am developing a PIC MCU program on an ansi-compliant compiler (Microchip XC8). There are two operation modes, determined via macros during compilation time. So that I don't want to duplicate one function-like macro due to one line of code, I would like to know if there is any way to write a macro such as

#define FOO //

so that when FOO is substituted it will actually cancel the rest of the line.

Writing a function instead of a macro is out of the question because the delay generated by function calls would disrupt the tight timings of my program (around some microseconds).

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
André Medeiros
  • 810
  • 4
  • 13
  • If there were such a way, the compiler would complain about the invalid tokens `//`. – Daniel Fischer Jun 12 '12 at 19:20
  • This doesn't answer your question, but have you tried writing a function and forcing your compiler to inline it with suitable compiler-specific incantations? – Steve Jessop Jun 12 '12 at 19:30
  • @SteveJessop I admit I have absolutely no idea of how doing that. Can you give me some advice, please? – André Medeiros Jun 12 '12 at 19:34
  • For example on GCC you can add `__attribute__((always_inline))` on an inline function (that's an `__inline__` function in GNU89, since `inline` isn't added until C99). Your compiler may have something similar. – Steve Jessop Jun 12 '12 at 19:46

4 Answers4

6

You can't make a macro expand to comment out the line, no. // in a macro definition is a comment following the definition, it's not expanded, and IIRC there's a rule saying that you cannot construct a // using token-pasting. Even if you can, expanding it doesn't mean that the macro starts a comment. Basically, you don't get to change the comment syntax using macros.

You could do:

#if DO_NOTHING_MODE
    #define FOO(ARG1)
#else
    #define FOO(ARG1) ARG1
#endif

and use it like:

#define FUNCTION_LIKE_MACRO(ARG1, ARG2) \
    required line; \
    FOO(optional line;) \

Although a more common idiom is to design the macro to accept an expression as its argument, rather than a whole line:

#if DO_NOTHING_MODE
    #define FOO(ARG1) ((void)0)
#else
    #define FOO(ARG1) (ARG1)
#endif

and use it like FOO(optional line);

Either way, if the macro argument has commas in it, then the caller needs to enclose them in parentheses FOO((1,2)), although in C99 you can avoid that by making FOO a variadic macro:

#define FOO(...) (__VA_ARGS__)
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
5

You can use the #ifndef directive to achieve the same effect:

#ifndef FOO
   your_line_of_code
#endif

EDIT: @SteveJessop made me see I didn't pay attention to this sentence of the OP "I don't want to duplicate one function-like macro due to one line of code". Here is what could be done in that case, if duplicating the function-like macro is not wanted:

// When FOO is defined, BLA in FUNC macro is a no-operation (null statement)

#ifndef FOO
#define BLA() a++
#else
#define BLA()
#endif

#define FUNC()  \
   BLA();       \
   b++;
ouah
  • 142,963
  • 15
  • 272
  • 331
  • Not when `your_line_of_code` appears inside the definition of a function-like macro. (Questioner says, "I don't want to duplicate one function-like macro due to one line of code") – Steve Jessop Jun 12 '12 at 19:32
  • @SteveJessop agree I didn't pay attention to this sentence. I added an edit. – ouah Jun 12 '12 at 19:44
  • @SteveJessop well, by the way I also didn't notice you answered something similar in the meantime :) – ouah Jun 12 '12 at 19:50
  • yep, I pretty much could have left it to you. Still, I've banged on at length about the various different ways to define a do-nothing macro, so at least my answer isn't redundant. – Steve Jessop Jun 12 '12 at 19:51
3

Comments are removed from the source before macro replacement occurs, so there's no way to define a macro exactly like that. However, it is certainly possible to pass an additional parameter into the macro to specify which code it should generate, or conditionally define the macro depending on the mode for which you are compiling.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • The problem is that FOO is actually an object-like macro that I pass to a function-like macro that is used both in and outside of other function-like macros. Therefore, any conditional definitions require me to duplicate the whole outtermost function-like macro just because of one line. And program space is precious. – André Medeiros Jun 12 '12 at 19:40
  • With sufficient indirection, no repeated code should be required. Without a clear example of what you're dealing with, though, I don't know what to recommend. Can you provide an example of the macro definitions and how they are used? – James McNellis Jun 12 '12 at 19:44
1
#define FOO(...) __VA_ARGS__

And then use FOO(your code here) instead of FOO your code here in the macro.

If your platform doesn't have C99, you can instead use

#define FOO(x) x

and just make sure the argument doesn't contain a , not enclosed in ().

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711