Hi I have been trying to port LWIP to a new arm device. When compiling the code i get the error message:
"lwip/lwip-1.4.0/src/include/lwip/memp_std.h:35:23: error: expected ')' before numeric constant"
When I go to this file this and below this several similar macros is what I find on that line:
LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB")
If I remove the need for this macro with a define to deactivate the RAW functionality the error moves to the next LWIP_MEMPOL() macro.
The define it seems to want to put a ')' in front of is defined as this:
#define MEMP_NUM_RAW_PCB 1
The RAW_PCB is not defined but is "combined with MEMP_" to create an element in an enum.
I have tried to complie the whole ting with the -E option to get human redable object files and see if i can find any open '(' around the areas where MEMP_RAW_PCB apears and the substitution of MEMP_NUM_RAW_PCB to 1 but I have not found any by manual inspection yet.
Are there any suggestions on what can be going on here or what more I can do or look for to find the cause of the error?
I should maybe add that so far I don't call on any of the LWIP code from main() or any of the functions used in main().
I solved it with:
#ifndef MEMP_STD_H_
#define MEMP_STD_H_
... // memp_std.h codes ...
#endif //#ifndef MEMP_STD_H_
The error suggests you have unbalanced parentheses. The code you have provided thus far does not indicate where this problem is, but since ) is expected, it probably means the error is actually in the lines of code preceding the one you have shown.
Examine the code preceding the line you have shown (perhaps after using gcc -E) to check to see if all the parentheses are balanced.
If you're defining it with the dash-D option, it will generate the 1 by default, e.g.:
gcc -D 'MAX(A,B) ((A) < (B)? (B) : (A))' ...
Generates:
#define MAX(A,B) ((A) < (B)? (B) : (A)) 1
And you get the error: expected ‘)’ before numeric constant message at the line where the substitution occurs because of that trailing 1, e.g.:
int maxval = MAX(i,j);
// generates: int maxval = ((i) < (j)? (j) : (i)) 1;
Conversely, if you use the assignment operator to explicitly define the value, it will generate it the way you expected. E.g.:
int maxval = MAX(i,j);
// generates: int maxval = ((i) < (j)? (j) : (i));
Related
I am trying to understand the following macro from the following URL:
do { \
word _v(l) = vec_len (V); \
V = _vec_resize ((V), 1, (_v(l) + 1) * sizeof ((V)[0]), (H), (A)); \
(V)[_v(l)] = (E); \
} while (0)
what is the significance of _v(l)? Is it just a variable or something more?
The _v macro is defined in vec.h at line 207:
#define _v(var) _vec_##var
This prepends _vec_ before var. You can observe this by asking your favorite compiler to print the output of the preprocessor stage (-E flag for clang/gcc and /E for msvc).
#define _v(var) _vec_##var
word _v(l) = vec_len (V);
Is expanded into:
word _vec_l = vec_len (V);
It is a variable whose name is generated. The name probably includes the current line number to make it unique. Therefore using this macro twice in a line may or may not work.
To see what the macro expands to, run gcc -E to only preprocess the code but not compile it. Do a bit of research about this -E computer option, it is helpful in many similar cases as well.
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?
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:
http://ideone.com/5m2LYw
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.
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)
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
I was trying some awkward preprocessing and came up with something like this:
#include <stdio.h>
#define SIX =6
int main(void)
{
int x=6;
int y=2;
if(x=SIX)
printf("X == 6\n");
if(y=SIX)
printf("Y==6\n");
return 0;
}
gcc gives me the errors:
test.c: In function ‘main’:
test.c:10:8: error: expected expression before ‘=’ token
test.c:12:8: error: expected expression before ‘=’ token
Why is that?
The == is a single token, it cannot be split in half. You should run gcc -E on your code
From GCC manual pages:
-E Stop after the preprocessing stage; do not run the compiler proper. The output is in
the form of preprocessed source code, which is sent to the standard output.
Input files that don't require preprocessing are ignored.
For your code gcc -E gives the following output
if(x= =6)
printf("X == 6\n");
if(y= =6)
printf("Y==6\n");
The second = is what causes the error message expected expression before ‘=’ token
The preprocessor doesn't work at the character level, it operates at the token level. So when it performs the substitution, you get something equivalent to:
if (x = = 6)
rather than your desired:
if (x==6)
There are some specific exceptions to this, like the # stringification operator.
if(x=SIX)
is parsed as
if (x= =6).
So you get the error.
What toolchain are you using? If you are using GCC, you can add the -save-temps option and check the test.i intermediate result to troubleshoot your problem.
I suspect you have a space between the x= and the =6.
I am trying to write #define for ASSERT() using __VA_ARGS.
(This code is for an embedded processor which doesn't support all libc functions).
My source code is like this:
ASSERT(msg == NULL)
ASSERT in header file:
#define ASSERT(...) if(__VA_ARGS__) { printf("[ASSERT ERROR]" __VA_ARGS__ "\n"); }
The preprocessor output is like this, which results compilation error.
if(msg == NULL) { printf("[ASSERT ERROR]" msg == NULL "\n"); }
How do I fix the #define to get rid of compilation errors while keeping the code logically correct?
There's no reason for this to be a variadic macro, at least not with telling us more information about what exactly you're trying to do. A simple one-argument macro using the stringizing operator # will do the trick nicely:
#define ASSERT(x) if(x); else printf("[ASSERT ERROR] " #x "\n")
Also note that I omitted the semicolon at the end and wrote it as if(x); else instead of if(!(x)), so that all of the following code fragments compile correctly as you'd expect, or produce a compiler error as you'd expect:
// #1 - this must be an error, no semicolon
ASSERT(x)
// #2 - this must also be an error
ASSERT(x)
else
/*stuff*/ ;
// #3 - the else must go with the first if, not the inner if inside the macro
// expansion
if (x)
ASSERT(y);
else
/*stuff*/ ;
Your original macro definition fails test #3 above.
I have this code which works:
#include <stdio.h>
#define A(x) x B
#define B(x) C(x,
#define C(x,y) y x)
int main( void ) {
printf( A("1") ("2") "3" );
}
It prints 132 (the point of the A macro is to swap the thing which follows its parameters in brackets with everything after that until another closing bracket)
But if I use that within another macro:
#define Z(x) x
printf( Z( A("1") ("2") "3" ) );
I get the compile error "Unterminated function-like macro invocation".
I realise that this happens because the compiler is trying to process the arguments of Z independently, but I need to use its closing bracket as a marker. Is there a way I can make this work within macros? Changing the calling syntax isn't really an option.
p.s. Before I get any responses talking about what an awful thing this is to do, rest assured: this is not for real code. It is a problem which came up while making a toy program which uses define to simulate a new language inside C.
The easiest way to see what's going on is to change the test case a little.
#define A(x) x B
#define B(x) C(x,
#define C(x,y) y x] /* note close square bracket instead of close paren */
Y(A(1)(2)3)
preprocesses to Y(1 3 2]. This is because an intermediate stage of expansion looked like
Y(1 C(2,3)
at which point C ate the close paren that appeared to belong to Y in the original text and replaced it with a close bracket.
Now, what happens differently if A(1)(2)3 is inside a macro argument?
#define Z(x) x
Z(A(1)(2)3)
Because of argument prescan, the analogous intermediate stage of expansion is not
Z(1 C(2,3)
but rather
1 C(2,3
with Z squirrelled away on a hidden "pending expansions" stack. The preprocessor is, in effect, enforcing the textual appearance that that final close paren belongs to Z, and C is not allowed to borrow it.
The least-invasive way I can think of to achieve your original goal is
#define _A(x) x B
#define B(x) C(x,
#define C(x,y) y x)
#define Z(x) ZZ((_##x))
#define ZZ(x) ZZZ x
#define ZZZ(x) [x]
Z(A(1)(2)3)
preprocesses to [1 3 2]. We use the token paste operator to prevent Z's argument from being prescanned, so we can add a temporary extra set of parentheses for use by C. ZZ and ZZZ then strip them off again. The catch is that it's an error if you don't paste x with something, so we have to add a leading underscore to the definition of A, and it will be an error if the first token of Z's argument is ever not something that can be token-pasted after an underscore.
You might want to consider using M4 instead of trying to shoehorn this into the C preprocessor.
eclipse cdt is excellent to debug your questions. for eclipse, just hover over a macro to get started. here is detialed info on it:
C/C++ Software Development with Eclipse >> 2.1.7. Macro Expansion
for your second macro, eclipse shows the following:
int main (void) {
printf( Z( A("1") ("2") "3" ) );
}
Spotting the Error
Notice in the expansion #3 C("2", "3" just 'disappears. I take this as CDT's way of saying 'unterminated argument list'. Whatever the case for it disappearing, this is the method I prefer to take when debugging macros.
Using this tool makes it clear that in Expansion#2 (third image) we have an unterminated set of brackets, thus locating the error.
Understanding a Solution
After fiddling around a bit using this tool, I think this is what you were after:
printf( Z( (A("1") ("2") "3") ) );
yields (using gcc -E main.c -c)
printf( ("1" "3" "2") );
This is about the order in which the macros are processed. The simplest solution is to add additional parentheses around the Z argument.
printf( Z( (A("1")("2") "3")) );