1

I am trying to define a NOOP macro. I went through How do I implement a no-op macro or template in C++. However I am getting unused variable error. I cannot change the gcc flags. So I have to work around this. Can you please help? This is the code.

#define TRACE(...) 
int main() {
    int a = 10, b = 20;
    int c = 30;
    TRACE(a, b);
    TRACE(c);
} 

#define TRACE(...) (void)0 gives me error: 'va_start' was not declared in this scope, error: 'va_end' was not declared in this scope.

How to get around this?

Community
  • 1
  • 1
CHID
  • 1,625
  • 4
  • 24
  • 43
  • What is TRACE supposed to do? Is it supposed to suppress the unused warnings? – Qix - MONICA WAS MISTREATED Apr 02 '15 at 23:47
  • It should just convert to NOOPs. The program as such may be meaningless, but I am facing exactly the same situtation in a bigger code base. There are lots of TRACE macros. Now I dont want to go and comment everyone of them. So I want to change that macro to NOOP – CHID Apr 02 '15 at 23:49
  • Have a look at [C `#define` macro for debug printing](http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/) for a lot of information on a closely related subject. Actually, I think it should cover what you want. Which errors are you getting? Unused variables or undeclared macros (`va_start`, `va_end`), or both? You avoid the unused variables by using them; see the debug printing macro question. It is not clear where `va_start()` or `va_end()` are being used, but they're defined in `` and including that should resolve the error. – Jonathan Leffler Apr 02 '15 at 23:52
  • Have you considered using the [`assert`](http://pubs.opengroup.org/onlinepubs/009695399/functions/assert.html) macro? – autistic Apr 03 '15 at 00:05
  • @JonathanLeffler I am getting both va_start and va_end error and stdarg.h doesnt solve it :( – CHID Apr 03 '15 at 00:15
  • @undefinedbehaviour: I cannot use assert because sometimes the values of the variables can be 0 and that will cause a panic – CHID Apr 03 '15 at 00:15
  • 3
    You'll need to show the minimum code necessary to repro the `va_start`/`va_end` issue. The code shown is not that code -- at least on any machine I have access to. (See how to create an MCVE ([Minimal, Complete, Verifiable Example](http://stackoverflow.com/help/mcve)) or SSCCE ([Short, Self-Contained, Correct Example](http://sscce.org/)) -- two names and links for the same idea). What you've shown could produce unused variable warnings/errors, but not the `va_start`/`va_end` issues. – Jonathan Leffler Apr 03 '15 at 00:33
  • This code looks right and compiles just fine for me... TRACE(...) expands to nothing in both instances. Time for rebuild all? – Anders Nov 30 '15 at 07:52
  • Does your code literally say `#define TRACE(...)` or is there something else in place of the `...`? – Nate Eldredge Dec 15 '15 at 17:25

1 Answers1

0

You seem to have inadvertently posted the answer to your own question without realising it.

Allow me to describe a tangential feature in C that you probably don't know about. It is a most useful feature when you're debugging software; it allows you to assert that a condition is true and that condition will be checked during runtime (when you're running a debug build, that is).

That feature is assert. The neat thing about assert (aside from the fact that it introduces internal documentation which might aid maintenance) is that when you compile your programs as release builds, they will vanish from your machine code.

Section 7.2 of the C standard documents that the assert() macro expands to ((void)0), which you appear to have concluded would cause errors. Which errors? Both the TRACE you have defined in your example and the TRACE I would define to look like FUBAR are perfectly valid in C.

#define TRACE(...) 
#define FUBAR(...) ((void)0)
int main() {
    int a = 10, b = 20;
    int c = 30;
    TRACE(a, b);
    FUBAR(c);
}

To emphasize, the code above compiles and runs as you should expect it to! After all, FUBAR is how assert is required to be implemented. There is another alternative, which I was hinting towards in the comments, if for some reason the above code doesn't work:

#include <assert.h>
#define TRACE(A,...) assert(A || 1)

These two va_start and va_end errors you see are caused by something else that we can't see in this question. If I had to hazard a guess, I'd suggest that you've forgotten to #include <stdarg.h>. Sorry, I can't help you more with these two errors until you post an MCVE. I would normally wait for such an MCVE, but it seems you were prompted for one over six months ago and have yet to respond... If you do, please ping me and I'll try to update my answer :)

autistic
  • 1
  • 3
  • 35
  • 80
  • And how would this avoid warnings about unused variables when the asserts are disabled? And how does a C++ solution/C++ code help for a question tagged 'C'? – Jens Dec 15 '15 at 12:32
  • @Jens Regarding the warnings, I'm sure someone as wise as you can see that there is more code that the OP has not shown... Apologies, sir. We can't all be perfect... I think if you look at my profile you will see that I should know better (89% of my reputation comes from the C tag). Unfortunately I made a mistake and saw "C++" in the question, so I assumed it was a C++ question. As I said, we can't all be perfect. – autistic Dec 15 '15 at 17:27