I'm trying to clean up my code for colouring strings. Here's what I have to prefix a red ANSI colour to a string, then suffix it with a reset colour.
#define GET_RED_TEXT(x) “\x1B[31m” x “\x1B[00m”
However, when I try use it...
src/util.c:18:15: error: expected expression
char *temp = GET_RED_TEXT("error: ");
^
includes/util.h:14:25: note: expanded from macro 'GET_RED_TEXT'
#define GET_RED_TEXT(x) “\x1B[31m” x “\x1B[00m”
^
src/util.c:22:14: error: expected ';' at end of declaration
va_end(arg);
^
;
Any ideas whats up with my macro?
Your macro has smart quotes in (“, ”) not real quotes (").
Also, as a matter of good practice, put a bracket round the definition, and x, e.g.:
#define GET_RED_TEXT(x) ("\x1B[31m" (x) "\x1B[00m")
You appear to have copied the code from some place and the double quotes are not valid try this
#define GET_RED_TEXT(x) "\x1B[31m" x "\x1B[00m"
copy and paste it into the editor please.
Note, that the your code is not highlighted properly.
Related
#define ID proj1
#define PROJ ID##_data.h
As per my requirements definition of PROJ should have proj1_data.h
When I print PROJ It should give proj1_data.h ,
Please help me to get the desired result. Thanks in advance !
You can only print a string. So to print PROJ, you would need to turn it into a string.
#define STRINGIZE(X) #X
#define STRINGIZE2(X) STRINGIZE(X)
STRINGIZE applies the stringizing operator on the argument. It turns the argument into a string, essentially by surrounding it with quotation marks, and escaping the contents as necessary to create a valid string. STRINGIZE2 is used to allow the argument to be expanded by the preprocessor before it is turned into a string. This is useful when you want to stringize the expansion of a macro instead of the macro itself. For example STRINGIZE2(__LINE__) will result in a string that represents the current line in the file, e.g. "1723". However, STRINGIZE(__LINE__) results in the string "__LINE__".
Your definition of PROJ faces a similar issue. It actually results in the token ID_data..h rather than proj1_data.h. You need a level of expansion indirection to allow ID to expand before you concatenate.
#define PASTE(X, Y) X ## Y
#define MKFILE(X) PASTE(X, _data.h)
#define PROJ STINGIZE2(MKFILE(ID))
Using STRINGIZE2 allows the MKFILE invocation to expand. Allowing MKFILE to invoke PASTE allows the ID token to expand.
When I run the following code,
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("%d",4*X+2);
return 0;
}
I am getting the following output:
Error: Undefined symbol 'X'
Can someone please explain the output?
It is because the macro expects and argument since its defined with parentheses.
You would need to define it as
#define X 4+Y and #define Y X+3. Then you would run into another trouble because of cyclic definition in macros.
To be even more correct, as Drew suggested; when the example would be compilable when defining macros one usually puts the parentheses around expression to ensure expected operator precedence.
So your best shot would be:
#define X (4+Y)
#define Y (X+3)
Very close to your initial example, just a space character between name of a macro and its definition. However, it is still impossible to properly expand the macro due to the cyclic reference.
How to check what happened:
You can use gcc -E, which outputs a pre-processed file. It generates lots of output so I used tail. I also used 2>err to redirect error stream to a file, so the output is clear.
luk32:~/projects/tests$ gcc -E ./cyclic_macro_with_no_spaces.c 2> err | tail -n 6
int main()
{
printf("%d",4*X+2);
return 0;
}
luk32:~/projects/tests$ gcc -E ./cyclic_macro.c 2> err | tail -n 6
int main()
{
printf("%d",4*(4+(X+3))+2);
return 0;
}
In 1st example the X did not expand at all. While in the latter both macros got expanded, although only one. Giving the same output that Geoffrey presented in his answer.
Whether no space is a typo or not there is an undefined symbol 'X'. For different reason that are possible to trace by analyzing err files.
If the macros are left as invalid function-like macros, they are not getting expanded at all because you did not call it with parentheses. So X is never replaced with anything by the pre-processor, and is the reason for the Undefined symbol 'X' in your sample code.
If you wanted this to be expanded you would have to call it with parentheses like this:
printf("%d",4*X()+2);
This though would just error out when pre-processed as 4+Y and X+3 are not valid macro parameter names.
If your answer is corrected somewhat so that those defines are proper defines, and not function-like macros, ie:
#define X (4+Y)
#define Y (X+3)
You have a circular reference between the defines...
X -> Y -> X... etc.
Since it will only expand the macro once, it is getting expanded to
printf("%d",4*(4+(X+3))+2);
This explains why X is the undefined symbol in this use case.
You miss spaces
#define X (4+Y)
#define Y (X+3)
i am writing in c, using Visual c++.
The compiler gives me the errors with the code below:
#define SIZE 3;
int myMatrix[SIZE][SIZE];
void funcMatrix(int M[SIZE][SIZE]);
The errors i get:
error C2143: syntax error : missing ']' before ';'
error C2059: syntax error : ']'
Ive tried declaring the constant differently, inside main and outside. It still doesn't work.
Would really appreciate it if someone can help me out...
You should use #define SIZE 3.
Preprocessor works as a raw string substitution, so with #define SIZE 3; your SIZE is replaced with 3; and you get:
int myMatrix[3;][3;];
void funcMatrix(int M[3;][3;]);
as a final result, hence the errors. This is a common error, then you get used to place ; at the end of C expression. However the preprocessor #define-s are not C code actually, but a simple (or not so simple) string processing operation which occurs before compilation.
In your code SIZE will be replaced by the define in this case 3; so you'll have
int myMatrix[3;][3;];
void funcMatrix(int M[3;][3;]);
Which causes a syntax error, so use #define SIZE 3 (without the ;) instead of #define SIZE 3;.
A #define NAME literally inserts whatever value comes after NAME.
Your macro expands to
int myMatrix[3;][3;];
Remove the ; in the macro definition.
you change :
#define SIZE 3;
to
#define SIZE 3
You need to remove the ; after the #define SIZE 3.
#defines don't require a semicolon
#define SIZE 3 not #define SIZE 3;
You can see what the compiler sees.
It can be a mess if you don't comment out included header files,
and I don't know how to do it in Visual C++,
but with GCC you run
gcc -E xx.c > xx.e
and you see what your code expands to after the #define's are processed.
There must be some way to do that with Visual C++ too.
Then you can still compile the .e file as c code.
#define SOUND_SPEED 0.034;
int rtt; //round trip time in microsecond
double distance;
distance = (double)(rtt*SOUND_SPEED)/2;
It complains error: expected expression before '/' token. Was is it bacause I can't use macro to define decimals or what?
Drop the semicolon:
#define SOUND_SPEED 0.034;
^
If you keep it the generated code will look like this:
distance = (double)(rtt*SOUND_SPEED;)/2;
^
#define SOUND_SPEED 0.034;
^
Do not use the trailing ;
Actually you should never terminate a macro with a ;:
PRE11-C. Do not conclude macro definitions with a semicolon
https://www.securecoding.cert.org/confluence/display/seccode/PRE11-C.+Do+not+conclude+macro+definitions+with+a+semicolon
You're using C, but you're trying to use a C++ style // comment. Depending on your compiler, that may not be allowed.
Edit: In fact, gcc -c89 -ansi gives that exact error message for a // comment and a totally different one for the extraneous ; in the define.
I'm trying to do something like:
#define __attribute__((aligned(2))) __attribute__((space(prog),aligned(2)))
but the compiler yields :
error: "(" may not appear in macro parameter list
Questions: What gives? How can I do a literal text replace, no bells, no frills ?
As soon as you start with a parenthesis, you're defining a macro with arguments, and that's bound to some rules.
So you can do, for example:
#define succ(x) (x + 1)
But you can't do:
#define pred(x + 1) x
The preprocessor only does a very limited set of pattern matching.
What you could do instead is something like:
#define __aligned2__ __attribute__((space(prog),aligned(2)))
And use that define instead. If that's not sufficient for your needs, you'll need to do some custom preprocessing using sed instead.
This is not possible with the C preprocessor. You can only define "literal txt replace"s, as you put it, if the text you want to replace is a single identifier ("object-like macro" in C standard parlance). What you wrote causes the preprocessor to think you're trying to define a "function-like macro", with a parameter named "(aligned(2))", which is a syntax error.
I would deal with this problem by wrapping the entire __attribute__ construct in an object-like macro:
#if appropriate condition
#define ATTRIBUTE_ALIGNED_2 __attribute__((space(prog),aligned(2)))
#else
#define ATTRIBUTE_ALIGNED_2 __attribute__((aligned(2)))
#endif
and then replacing __attribute__((aligned(2))) with ATTRIBUTE_ALIGNED_2 throughout the source code.