I want to print the value of the variable, which has the highest value. I want to do this by using the preprocessor, but I don't know how to do this. It's easy to do this by using if-else, but how to do that by using preprocessor?
This is my code
#include <stdio.h>
#define MAX(a,b,c)
#if a > (b && c)
# define a
#endif
#if b > (a && c)
# define b
#else
# define c
#endif
int main (void)
{
int wynik;
int a = 6;
int b = 13;
int c = 9;
wynik = MAX(a,b,c);
printf("%i", wynik);
return 0;
}
And this is the errors from my terminal
E:\skrypty_c>gcc -o Cwiczenie12_4.exe Cwiczenie12_4.c
Cwiczenie12_4.c: In function 'main':
Cwiczenie12_4.c:17:11: error: expected identifier or '(' before '=' token
int c = 9;
^
Cwiczenie12_4.c:18:23: error: expected expression before ';' token
wynik = MAX(a,b,c);
That's not how it works. Your max-of-three macro would be something like
#define MAX(a, b, c) ((a) <= (b)? (b) <= (c)? (c) : (b) : (a) <= (c)? (c) : (a))
but frankly, it would be much better as a function:
inline int max(int a, int b, int c) {
if(a <= b) {
if(b <= c) return c;
return b;
}
return a <= c? c : a;
}
Preprocessor cannot be used for that. Preprocessor does not know anything about the c variables and sysntax.
You cant use any preprocesor conditional expressions in the #defines.
if you want to use macro to find max of 3 tokens you need to use C expressions for that as it will be evaluated runtime (or compile time), not during the preprocessing
#define MAX(a,b,c) (a) > (b) ? ((a) > (c) ? (a) : ((c) > (b) ? c : (b))) : ((b) > (c) ? (b) : (c))
You cannot check the value of runtime variables through preprocessor conditionals. They can check only the values of preprocessor level symbols. For example
#define A 5
#if (A > 3)
...
#endif
Looking at the way you used #define and #if, my guess is that you meant defining some sort of preprocessor level function having #define a similar role of def func (): in Python. That's not how it works.
#define A expr just replaces the symbol A with expression expr in the current source file before compilation. No occurrences of A, no substitutions
#define A(b,c) expr is like the previous one, but uses b,c like function parameters, and they are expanded in the replaced in expression expr using the values passed when the macro is called.
#if expr or #ifdef symbol or #ifndef symbol are ways to check the value or even the simple definition of symbols previously defined through #defines (or through compiler option -D) in order perform conditional compilation of whole sections of code. These sections are closed with #endif, and alternative sections in case of false conditions can be compiled using #else and #elif directives.
What you can do, and I suspect it was your actual purpose, is to define a macro finding the maximum value among its parameters:
#define MAX(a,b,c) \
(((a>b) && (a>c))? a : ((b>a) && (b>c))? b : c ))
I used ternary operator to calculate the max value.
Note: the \ character allows to place a macro on multiple lines. It needs to be the last character of the line.
Related
I have code containing many lines such as:
static_assert(sizeof(my_stuct)==42, "check struct size");
and I want to compile on a compiler which has no static_assert implemented. So I want these lines to become no-op. I've tried:
#define static_assert(COND, MSG)
it works fine but I get a warning with clang compiler:
warning: extra ';' outside of a function [-Wextra-semi]
Is there a simple no-op C statement to be used outside functions which terminates with a semicolon and which can be used repeatedly?
I want to compile on a compiler which has no static_assert implemented. So I want these lines to become no-op.
Why not combining Lundin's answer (checking whether the current compiler has it implemented or not) with an implementation of static_assert (which is not hard to do)?
Copying the implementation from PDCLib (which is CC0 licensed):
/* with dodgy implementations, you could also #ifndef static_assert */
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
#define _PDCLIB_cc( x, y ) x ## y
#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
#define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
#endif
For a given expression e and message m, this declares an anonymous enumeration with one member, the name of which is _PDCLIB_assert_ concatenated with the current source file line (__LINE__) (so you can have multiple static_assert() per source file). This member is set to 1 divided by 1 if the expression e is true, or divided by 0 if the expression is false, which leads to output like this for a failed assert:
./path/to/source.c:57:94: warning: division by zero [-Wdiv-by-zero]
#define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
^
./path/to/header.h:571:1: note: in expansion of macro 'static_assert'
static_assert( false, "test" );
^
./path/to/source.c:57:62: error: enumerator value for '_PDCLIB_assert_571' is not an integer constant
...
It's not pretty, but it's perfectly C89-compliant, tested, and servicable.
Feel free to rename from _PDCLIB_* to anything you prefer.
My solution so far:
#define static_assert(COND, MSG) extern int __static_assert_dummy__
works fine but seems ugly to me!
Since this is a C11 feature, the answer is quite trivial: simply check if the compiler supports C11.
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112
static_assert(sizeof(my_stuct)==42, "check struct size");
#endif
The opposite, to make this a no-op in the absence of standard C, and thereby remove the need for the above compiler switches all over the place, is this:
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
#define static_assert(cond, str) struct dummy_t
#endif
Though remember that static_assert requires #include <assert.h>, unlike the C11 keyword _Static_assert.
Tested only very quickly, but how about:
#define static_assert(COND, MSG) extern int _no_static_assertion
or something? Repeating an extern should be fine.
Having this statement:
dist[i]= min(dist[i],dist[j]+edge[j][i]);
How safe the corresponding following macro (in C) is:
#define MIN(d[i], edge[i][j]) (d[i] < edge[i][j] ? (d[i]) : (edge[i][j]))
Thank you.
If you want a Min definition macro you need to do it like that
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
Like said in comment, macros need identifiers and not array, not even variables. But this macros is note type safe. Why not using fmax and fmin? It's better and you dont have to create a macro
I have this been given C code where the heading statement includes the following:
#define, EQ(a, b) ((a) == (b))
What does it mean?
The comma is an error that will prevent the code from compiling: I'll assume that it's a typo.
Given:
#define EQ(a, b) ((a) == (b))
This defines a macro for the equality operator ==.
Using this macro later in the code, you can type, e.g.:
if (EQ(2+2, 4))
instead of:
if (2+2 == 4)
Not very useful, really.
It means nothing: this code is ill-formed. The token immediately following a #define must be an identifier, which , is not.
If the , were to be removed, this would define a function-like macro named EQ that takes two arguments.
Let's take it step by step
#define MAX 10
This will replace every instance of the word "MAX" by 10 in your code file. this is very much like defining a constant variable with one major difference. The interpretation of #define statement is done way before compilation. which helps for an example to use MAX as an array size. Which would have caused a compiler error in many cases if you have used a variable instead.
you can use cpp <filename.c> command in Linux terminal to see what will happen when a macro is executed.
for an example this code:
#define MAX 10
int numbers[MAX];
after preprocessing (i.e. interpretation of the preprocessor macros)
int numbers[10];
note that the #define statement will vanish once interpreted.
This takes us to another example
#define square(x) (x * x)
every instance of square(x) in our code will not only be replaced by (x * x) but also the value of x will be replaced. Which has an effect similar to function deceleration but again it is different
so
square(5) will be replaced by (5 * 5)
Finally our example
#define, EQ(a, b) ((a) == (b))
This will replace every instance of EQ(a, b) by ((a) == (b))
so for an example
EQ(4, 5) will be replaced by ((4) == (5))
Now what does "==" mean? it is the "check if equal" if 4 and 5 are equal the whole expression would evaluate as 1 (which obviously is not true) and thus this expression will end up to be evaluated as 0.
Which more or less like the effect of this function
int EQ(int a, int b)
{
return (a == b);
}
Which could be also written as
int EQ(int a, int b)
{
if (a ==b) return 1;
if (a !=b) return 0;
}
Note that with the macro we avoided two variable declarations and there is no function call really and it is in general quicker. This advantage will be obvious if you have a slower processor (or microprocessor).
Finally let me state the obvious
#define simple_macro 5
int some_integer_variable = 10;
.
.
.
some_integer_variable = simple_macro;
simple_macro = 12; /* illegal statement */
simple_macro++; /* illegal statement */
because after running the preprocessor this will be
int some_integer_variable = 10;
.
.
.
some_integer_variable = 5;
5 = 12;
5 ++;
Oh! I might have talked too much but let me leave you with this (obvious) code
#define MAX 10
int variable = MAX; /*this is a MAX variable */
char some_string[] = "the MAX value"; /* no replacement will happen here */
int variable_MAX; /* no replacement will happen here */
after running the preprocessor will be
int variable = 10;
char some_string[] = "the MAX value";
int variable_MAX;
Define a macro MAX3 that gives the maximum of three values.
This is what I came up with:
#define MAX3(a,b,c) ( ((a) > (b)) && ((a) > (c)) ) ? (a) : ((b) > (c)) ? (b) : (c)
This is hard to read. Is there a way to write an equivalent macro with if–else statements?
Having an expression-like macro with statements inside is not possible in standard C99 language (because in C99 statements and expressions are deeply different, both syntactically and semantically).
However, GCC (and some other compilers with extensions inspired by GCC, e.g. clang) provides a nice extension for that : statement expressions (the documentation gives an example related to your question). With that extension you could code something like
#define MAX3(A,B,C) ({ int a=(A); int b=(B); int c=(C); int m; \
if (a>b) m=a; else m=b; \
if (c>m) m=c; \
m; }) /* bad macro */
however that still won't work if you use that macro like e.g.
int badex(int x, int y) {
int a= x+y; int m= x*y; int d=x-y;
return MAX3(a,m,d);
}
I hope you see why it won't work (name clashes e.g. between the a inside badex and the a inside MAX3 macro). So you need a way to have unique names at every invocation of your macro. Again, GCC provides a nice extension for that, the __COUNTER__ macro (expanded to a unique number, counting) used with concatenation in the preprocessor.
Then you'll code something like
#define MAX3(A,B,C) MAX3_COUNTED((A),(B),(C),__COUNTER__)
#define MAX3_COUNTED(A,B,C,N) ({ \
int a_##N=(A); int b_##N=(B); int c_##N=(C); \
int m_##N; \
if (a_##N>b_##N) m_##N = a_##N; else m_#N = b_##N; \
if (c_##N>m_##N) m_##N=c_##N; \
m_##N; }) /* better example */
Then the first invocation of our macro e.g. MAX3(i++,j++,k++) might expand to MAX3_COUNTED((i++),(j++),(k++),1) which gets expanded into something using a_1 b_1 ... and the second invocation, e.g. MAX3(a,m,d) expanded as MAX3_COUNTED((a),(m),(d),2) would use a_2 b_2 etc so is better.
And of course, defining a static inline max3(int a, int b, int c) function is cleaner (in particular because of side effects: your MAX3 macro gives naughty effects and results with a call like MAX3(i++,j++,k++) etc)
The general lesson about this is that you should when possible avoid macro (preferring inline functions), and when you absolutely need macros take care about name clashes and expansions.
Using GCC invoked as gcc -C -E shows you the preprocessed form of your program.
It's probably better to do it this way:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX3(a, b, c) MAX(a, MAX(b, c))
Or better still, use an inline function rather than resorting to old skool preprocesser abuse:
inline int max3(int a, int, int c) { return max(a, max(b, c)); }
It's a lot more robust than a macro and just as efficient.
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 . */