Reputation: 7225
I've been working on a piece of code that had an overlooked derp in it:
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#define MAX_N_LENGTH
/*function prototypes*/
int main(){
...
}
It should be easy to spot with the context removed: #define MAX_N_LENGTH
should have read #define MAX_N_LENGTH 9
. I have no idea where that trailing constant went.
Since that macro was only used in one place in the form of char buf[ MAX_N_LENGTH + 1]
, it was extremely difficult to track down and debug the program.
Is there a way to catch errors like this one using the gcc compiler?
Upvotes: 4
Views: 1399
Reputation: 37834
You can use the preprocessor to catch when a macro is either 0 or defined without a value:
#define VAR
#if VAR+0 == 0
#error "VAR is either 0 or defined without a value."
#endif
Upvotes: 1
Reputation: 9804
You can use char buf[1 + MAX_N_LENGTH]
, because char buf[1 +]
should not compile with the error message error: expected expression before ']' token
:
Upvotes: 3
Reputation: 60068
What you have there isn't an undefined macro. It's an empty macro. And defined empty macros are perfectly legit, because you can test for their definedness.
They're used quite a lot in the implementation header files, although all those empty macros will be in the implementation namespace, which means they will either contain two underscores or an underscore followed by an uppercase letter.
What you could do is test whether you have an empty macro that's not in the implementation namespace, and you can do that with:
cpp -dM YOUR_FILE.c |
cut -d\ -f2- | grep '^[a-zA-Z0-9_]* $' |grep -v -e __ -e ^_[A-Z]
For your example, it should output just MAX_N_LENGTH
.
Upvotes: 2
Reputation: 10863
It's not possible to catch this error in the general sense, because it isn't an error. There's plenty of cases where this sort of behavior is desired, so the compiler cannot treat it as an error or a warning.
If you can track the error down to a line, using gcc's -E
command line argument will cause it to output the result of the preprocessor. In that case, your char line would have turned to char buf[+1]
, which is legal C code, but might catch your attention because you expected it to be char buf[9+1]
. -E
causes gcc to print those results, so you would actually see char buf[+1]
in the output of gcc.
Issues like this are why C++ discourages use of define macros in this way (C++, of course, has more alternatives than C which makes it easier to discourage them)
Upvotes: 1