I need to map a macro to a right value depending on the option selected e.g
#define A { if (fel == 1) x; if(fel != 1) y; }
I want A to assume the value of x if fel is 1, else it must assume the value y.
Where am I missing it?
Macros are preprocessor directives, meaning - they are expanded before the compilation and before runtime.
So, the way you've written this, A will literally be replaced by { if (fel == 1) x; if(fel != 1) y; }, not by x or y.
Macros can be avoided most of the time. Why not just use A as variable, not as macro?
If fel is compile-time known constant OR a macro itself, there are options with #if, but it looks like it's a normal variable.
You can't. Macro substitution is done at preprocessing stage and you can't set it based on a runtime condition.
Instead you can define A as a variable:
A = (fel == 1)? x: y;
Define the macro using the ternary operator:
#define A ((fel == 1) ? x : y)
The macro will only work if you use it in a context where fel and x and y are all in scope.
if is a statement, not an expression, thus it doesn't return any value. You need to write it as an expression, like using ternary operator, as suggested by others, or use GCC extension
Related
I am trying to use #if macros by defining the type of operation to invoke the right code, So i made a very simple example similar to what I am trying to do:
#include <stdio.h>
enum{ADD,SUB,MUL};
#define operation ADD
int main()
{
int a = 4;
int b = 2;
int c;
#if (operation == ADD)
c = a+b;
#endif
#if (operation == SUB)
c = a-b;
#endif
#if (operation == MUL)
c = a*b;
#endif
printf("result = %i",c);
return 0;
}
But unfortunately that does not work I get the following result = 8... if I replace The operation with numbers it works fine .... But i want it to work as it is described above.
Any help
The preprocessor is a step that is (in a way) done before the actual compiler sees the code. Therefore it has no idea about enumerations or their values, as they are set during compilation which happens after preprocessing.
You simply can't use preprocessor conditional compilation using enumerations.
The preprocessor will always consider that as false:
#if IDENT == IDENT
It can only test for numeric values.
Simplify your code and feed it to the preprocessor:
enum {ADD,SUB,MUL};
#define operation ADD
int main()
{
(operation == ADD);
}
The result of the preprocessor output is:
enum {ADD,SUB,MUL};
int main()
{
(ADD == ADD);
}
As you see, the enumerate value hasn't been evaluated. In the #if statement, that expression is just seen as false.
So a workaround would be to replace your enumerate by a series of #define:
#define ADD 1
#define SUB 2
#define MUL 3
like this it works. Output of preprocessor output is now:
int main()
{
int a = 4;
int b = 2;
int c;
c = a+b;
# 28 "test.c"
printf("result = %i",c);
return 0;
}
the solution is:
either rely at 100% on the preprocessor (as the solution above suggests)
or rely at 100% on the compiler (use enums and real if statements)
As others have said, the preprocessor performs its transformations at a very early phase in compilation, before enum values are known. So you can't do this test in #if.
However, you can just use an ordinary if statement. Any decent compiler with optimization enabled will detect that you're comparing constants, perform the tests at compile time, and throw out the code that will never be executed. So you'll get the same result that you were trying to achieve with #if.
But i want it to work as it is described above.
You seem to mean that you want the preprocessor to recognize the enum constants as such, and to evaluate the == expressions in that light. I'm afraid you're out of luck.
The preprocessor knows nothing about enums. It operates on a mostly-raw stream of tokens and whitespace. When it evaluates a directive such as
#if (operation == SUB)
it first performs macro expansion to produce
#if (ADD == SUB)
. Then it must somehow convert the tokens ADD and SUB to numbers, but, again, it knows nothing about enums or the C significance of the preceding code. Its rule for interpreting such symbols as numbers is simple: it replaces each with 0. The result is that all three preprocessor conditionals in your code will always evaluate to true.
If you want the preprocessor to do this then you need to define the symbols to the preprocessor. Since you're not otherwise using the enum, you might as well just replace it altogether with
#define ADD 1
#define SUB 2
#define MUL 3
If you want the enum, too, then just use different symbols with the preprocessor than you use for the enum constants. You can use the same or different values, as you like, because never the twain shall meet.
Another solution would be to have the enum in an included header file.
i'm trying to define the following macro:
#define UTF8_2B(c) if((0xc0 & c) == 0xc0){return 1;}
But i'm met with the error:
expected expression before ‘if’
The macro is called like so:
int i = UTF8_2B(c);
Where c is an unsigned char read from a file.
Why does this happen? Can you not use if else statements in macros?
Also, I've read that it's not a good idea to use semicolon in your macros, but i didn't understand why.
I'm new to c so the more thorough the answer the better.
C (and C++) preprocessor macros are essentially "copy-paste" with argument substitution. So your code becomes:
int i = if((0xc0 & c) == 0xc0){return 1;}
And this is invalid syntax.
You're assigning the result of your macro to a variable. You cannot do that with the current macro (return returns from the current function, and doesn't return something to be assigned to i: so not what you want).
If you're using gcc, you can view what your pre-processed code looks like with the -E command line.
So you can use if in macros, but not in macros that are used like functions, which are supposed to return a value.
Moreover:
if c is a complex expression, operator precedence could make the macro generate wrong code
the macro should provide a way to require semicolon, so IDEs and human readers see that as a normal function
I'd propose a simple test instead (which yields 1 if true, 0 otherwise), which meets the "need semicolon" standard and is safe to use with a complex c expression:
#define UTF8_2B(c) ((0xc0 & (c)) == 0xc0)
The ternary operator exists for this purpose. Assuming you want 1 if true and 0 if false, the correct macro is:
#define UTF8_2B(c) (((c) & 0xC0) == 0xC0 ? 1 : 0)
Now you can assign the result. Using return in a macro will return from the enclosing function, not from the macro, and is almost always a bad idea.
I wonder to know is it possible to send a parameter to a #define macro for selecting different output
For example:
#define Row(1) LPC_GPIO0
#define Row(2) LPC_GPIO3
#define Row(3) LPC_GPIO2
Then in my code I create a loop for sending the parameter
Row(x)
This macro syntax doesn't exist.
Moreover, it can't possibly exist, because macros are expanded before the compiler compiles the code. If your x isn't a compile time constant, there would never be a way to determine what to replace in the source code for the macro invocation.
If you need to index some values, just use an array, e.g. (assuming these constants are integers):
static int rows[] = { 0, LPC_GPIO0, LPC_GPIO3, LPC_GPIO2 };
Writing
rows[x]
would have the effect you seem to have expected from your invalid macro syntax.
if you want to use macros
#define GPIOx(x) GPIO##x
and GPIOx(1) will expand to GPIO1
If you want these calculated at runtime there is a way to do what you want
#define Row(x) (x == 1 ? LPC_GPIO0 : (x == 2 ? LPC_GPIO3 : (x == 3 ? LPC_GPIO2 : ERROR_VALUE)))
Though this gets messy as the number of options increases
Also, even if you do want this evaluated at compile time, most optimizing compilers would do that for you as long as x is a constant
Let's say I define macro with arguments, then invoke it as follows:
#define MIN(x,y) ((x)<(y)?(x):(y))
int x=1,y=2,z;
z=MIN(y,x);
Given that (a) macro works as text substitution, (b) that actual args here are like formal args, only swapped, -- will this specfic z=MIN(y,x) work as expected ? If it will, why ?
I mean, how preprocessor manages not to confuse actual and formal args ?
This question is about technicalities of C compiler. This is not c++ question.
This question does not recommend anybody to use macros.
This question is not about programming style.
The internal representation of the macro will be something like this, where spaces indicate token boundaries, and #1 and #2 are magic internal-use-only tokens indicating where parameters are to be substituted:
MIN( #1 , #2 ) --> ( ( #1 ) < ( #2 ) ? ( #1 ) : ( #2 ) )
-- that is to say, the preprocessor doesn't make use of the names of macro parameters internally (except to implement the rules about redefinitions). So it doesn't matter that the formal parameter names are the same as the actual arguments.
What can cause problems is when the macro body makes use of an identifier that isn't a formal parameter name, but that identifier also appears in the expansion of a formal parameter. For instance, if you rewrote your MIN macro using the GNU extensions that let you avoid evaluating arguments twice...
#define MIN(x, y) ({ \
__typeof__(x) a = (x); \
__typeof__(y) b = (y); \
a < b ? a : b; \
})
and then you tried to use it like this:
int minint(int b, int a) { return MIN(b, a); }
the macro expansion would look like this:
int minint(int b, int a)
{
return ({
__typeof__(b) a = (b);
__typeof__(a) b = (a);
a < b ? a : b;
});
}
and the function would always return its first argument, whether or not it was smaller. C has no way to avoid this problem in the general case, but a convention that many people use is to always put an underscore at the end of the name of each local variable defined inside a macro, and never put underscores at the ends of any other identifiers. (Contrast the behavior of Scheme's hygienic macros, which are guaranteed to not have this problem. Common Lisp makes you worry about it yourself, but at least there you have gensym to help out.)
It will work as expected.
#define MIN(x, y) ((x) < (y) ? (x) : (y))
int x=1,y=2,z;
z = MIN(y, x);
becomes
int x=1,y=2,z;
z = ((y) < (x) ? (y) : (x));
Does the above have any syntactic or semantic errors? No. Therefore, the result will be as expected.
Since you're missing a close ')', I don't think it will work.
Edit:
Now that's fixed, it should work just fine. It won't be confused by x and y any more than it would be if you has a string x with "x" in it.
First off, this isn't about the C compiler, this is about the C Pre-processor. A macro works much like a function, just though text substitution. What variable names you use make no impact on the outcome of the macro substitution. You could have done:
#define MIN(x,y) ((x)<(y)?(x):(y))
int blarg=1,bloort=2,z;
z=MIN(bloort,blarg);
and get the same result.
As a side node, the min() macro is a perfect example of what can go wrong when using macros, as an exercise you should see what happens when you run the following code:
int x,y,z;
x=1;y=3;
z = min(++x,y);
printf("%d %d %d\n", x,y,z); /* we would expect to get 2 3 2, but we get 3 3 3 . */
I'm trying to decide whether to implement certain operations as macros or as functions.
Say, just as an example, I have the following code in a header file:
extern int x_GLOB;
extern int y_GLOB;
#define min(x,y) ((x_GLOB = (x)) < (y_GLOB = (y))? x_GLOB : y_GLOB)
the intent is to have each single argument computed only once (min(x++,y++) would not cause any problem here).
The question is: do the two global variables pose any issue in terms of code re-entrancy or thread safeness?
I would say no but I'm not sure.
And what about:
#define min(x,y) ((x_GLOB = (x)), \
(y_GLOB = (y)), \
((x_GLOB < y_GLOB) ? x_GLOB : y_GLOB)
would it be a differnt case?
Please note that the question is not "in general" but is related to the fact that those global variables are used just within that macro and for the evaluation of a single expression.
Anyway, looking at the answers below, I think I can summarize as follows:
It's not thread safe as nothing guarantees that a thread is suspended "in the middle" of the evaluation of an expression (as I hoped instead)
The "state" those globals represent is, at least, the internal state of the "min" operation and preserving that state would, again at least, require to impose restrictions on how the function can be called (e.g. avoid min(min(1,2),min(3,1)).
I don't think using non-portable constructs is a good idea either so I guess the only option is to stay on the safe side an implement those cases as regular functions.
Silently modifying global variables inside a macro like min is a very bad idea. You're much better off
accepting that min can evaluate its argument multiple times (in which case I'd call it MIN to make it look less like a regular C function), or
write a regular or inline function for min, or
use gcc extensions to make the macro safe.
If you do any of these things, you eliminate the global variables entirely and hence any questions about reentracy and multi-threading.
Option 1:
#define MIN(x, y) ((x) < (y) ? (x) : (y))
Option 2:
int min(int x, int y) { return x < y ? x : y; }
Of course, this has the problem that you can't use this version of min for different argument types.
Option 3:
#define min(x, y) ({ \
typeof(x) x__ = (x); \
typeof(y) y__ = (y); \
x__ < y__ ? x__ : y__; \
})
The globals are not thread-safe. You can make them so by using thread-local storage.
Personally, I'd use an inline function instead of a macro to avoid the problem altogether!
Personally I don't think this code is safe at all, even if we don't consider multithreaded scenarios.
Take the following evaluation:
int a = min(min(1, 2), min(3, 4));
How will this expand properly and evaluate?
Evaluate min(1, 2) and assign value to x_GLOB (outer macro):
x_GLOB = 1
y_GLOB = 2
evaluate min, result is 1, assign to x_GLOB (for outer macro)
Evaluate min(3, 4) and assign value to y_GLOB (outer macro):
x_GLOB = 3 (uh-oh, 1 from the first expansion is now clobbered)
y_GLOB = 4
evaluate min, result is 3, assign to y_GLOB (for outer macro)
Evaluate min(a, b) where a is min(1, 2) and b is min(3, 4)
evaluate min of x_GLOB (which is 3) and y_GLOB (which is 3)
result of total evaluation is 3
Or am I missing something here?
Generally speaking, anytime you use global variables, your subroutine (or macro) is not re-entrant.
Anytime two threads access the same data or shared resource, you have to use synchronization primitives (mutexes, semaphores, etc) to coordinate access to the "critical section".
See Wikipedia reentrant page
It's not thread-safe. To demonstrate this, suppose that thread A calls min(1,2) and threadB calls min(3,4). Suppose that thread A is running first, and is interrupted by the scheduler right at the question mark of the macro, because its time slice has expired.
Then x_GLOB is 1, and y_GLOB is 2.
Now suppose threadB runs for a while, and completes the contents of the macro:
x_GLOB is 3, y_GLOB is 4.
Now suppose threadA resumes. It will return x_GLOB (3) instead of the right answer (1).
Obviously I've simplified things a bit - being interrupted "at the question mark" is pretty handwavy, and threadA doesn't necessarily return 3, on some compilers with some optimisation levels it might keep the values in registers and not read back from x_GLOB at all. So the code emitted might happen to work with that compiler and options. But hopefully my example makes the point - you can't be sure.
I recommend you write a static inline function. If you're trying to be very portable, do it like this:
#define STATIC_INLINE static
STATIC_INLINE int min_func(int x, int y) { return x < y ? x : y; }
#define min(a,b) min_func((a),(b))
Then if you have a performance problem on some particular platform, and it turns out to be because that compiler fails to inline it, you can worry about whether on that compiler you need to define STATIC_INLINE differently (to static inline in C99, or static __inline for Microsoft, or whatever), or perhaps even implement the min macro differently. That level of optimisation ("does it get inlined?") isn't something you can do much about in portable code.
That code is not safe for multithreading.
Just avoid macros, unless indispensable ("Efficient C++" books have examples of those cases).