What's the best way to define a between macro, which is type generic (char,int,long)
which will return true if a number is between to other numbers inputted.
I'm tried to google it, but I didn't find anything.
Edit: The order of the two boundaries given shouldn't matter. so it can be more general.
If you do something like:
#define BETWEEN(a, b, c) (((a) >= (b)) && ((a) <= (c)))
you are going to have problem with the double evaluation of a. Think what would happens if you do that with a functions that has side effects...
you should instead do something like:
#define BETWEEN(a, b, c) ({ __typeof__ (a) __a = (a); ((__a) >= (b) && ((__a) <= (c)) })
(edited because the result should not depend of the order of b and c):
#define BETWEEN(a, b, c) \
({ __typeof__ (a) __a = (a);\
__typeof__ (b) __b = (b);\
__typeof__ (c) __c = (c);\
(__a >= __b && __a <= __c)||\
(__a >= __c && __a <= __b)})
Firstly, don't use macros for things like this - use functions (possibly inline).
Secondly, if you must use macros, then what's wrong with e.g.
#define BETWEEN(x, x_min, x_max) ((x) > (x_min) && (x) < (x_max))
?
As per your subsequent edit, if you don't know the ordering of x_min and x_max then you could do this:
#define BETWEEN2(x, x0, x1) (BETWEEN((x), (x0), (x1)) || \
BETWEEN((x), (x1), (x0)))
The usual caveats about macros and side-effects etc apply.
Edit: removed space between macro & arguments for compilation
If all types are the same, how about:
/* Check if 'a' is between 'b' and 'c') */
#define BETWEEN(a, b, c) (((a) >= (b)) && ((a) <= (c)))
Note that if the types of a, b and c above are different, the implicit type conversions of C might make it wrong. Especially if you mix signed and unsigned numbers.
+1: A not-so-trivial question, since it involves the problem of the evaluation of macro parameters. The naive solution would be
#define BETWEEN(x,l1,l2) (((x) >= (l1)) && ((x) <= (l2)))
but "x" is evaluated twice, so there may be problems if the expression has side effects. Let's try something smarter:
#define BETWEEN(x,l1,l2) (((unsigned long)((x)-(l1))) <= (l2))
Very very tricky and not so clean, but...
#define BETWEEN_MIN(a, b) ((a)<(b) ? (a) : (b))
#define BETWEEN_MAX(a, b) ((a)>(b) ? (a) : (b))
#define BETWEEN_REAL(val, lo, hi) (((lo) <= (val)) && ((val) <= (hi)))
#define BETWEEN(val, hi, lo) \
BETWEEN_REAL((val), BETWEEN_MIN((hi), (lo)), BETWEEN_MAX((hi), (lo)))
See code running: http://ideone.com/Hb1vP
If I understand correctly, you will need 3 numbers, the upper limit, the lower limit and the number you're checking, so I would do it like this:
#define BETWEEN(up, low, n) ((n) <= (up) && (n) >= (low))
This assumes the between is inclusive of the upper and lower limits, otherwise:
#define BETWEEN(up, low, n) ((n) < (up) && (n) > (low))
Related
I am trying to create a program that uses macros for determining the mid-range for three values. The midrange is defined as:
midrange(a, b, c) = (min(a, b, c) + max(a, b, c)) / 2
For example:
midrange(3, 10, 1) = (min(3, 10, 1) + max(3, 10, 1)) / 2
= (1 + 10) / 2
= 11 / 2
= 5.5
I am still new to programming, and I am not sure if the syntax I am using for macro definitions is correct. My first question is, can I define a macro in the main function? My second question, should I use curly braces, normal parenthesis, or nothing at all for the body of the macro, that is, the replacement list?
This is what my program looks like for calculating the midrange of three integer values:
#include <stdio.h>
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
#define MAX(A, B) {(A) > (B) ? (A) : (B);}
int main(){
//scans the three values
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int min = MIN(MIN(a, b), c);
int max = MAX(MAX(a, b), c);
//defines new macro for calculating the midrange
//is this allowed/correct formatting and syntax?
#define MIDRANGE((min + max) / 2);
/* initializes variable mrange to equal to the value returned
function-like macro, MIDRANGE */
double mrange = MIDRANGE((min + max) / 2);
printf("The mid-range is: %lf", mrange);
return 0;
}
The reason why I declared the variable mrange as a double is because I want the value of the MIDRANGE macro to be precise, meaning that it will keep the decimal places after the division by 2 in the equation.
Any help is appreciated:)
You can declare a macro anywhere in the code, but unless you have a very specific reason to restrict its usage to a function, it typically appears in the beginning of the .c file or in a .h file.
Macros work by substitution. So if you have something similar to the following:
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
int main(void)
{
int min = MIN(MIN(a, b), c);
}
It will be preprocessed into:
int min = {({(a) < (b) ? (a) : (b);}) < (c) ? ({(a) < (b) ? (a) : (b);}) : (c);};
You can see this by yourself, if you are using GCC, with the command gcc -E source.c. This is obviously not what you wanted, and it will give you a compilation error.
We never use ; at the end of macros, neither put them in blocks. To avoid unexpected operator association with complicated expressions, we guard macro parameters and the whole macro within parentheses.
Your MIN macro should look somewhat like this:
#define MIN(A, B) ((A) < (B) ? (A) : (B))
Finally, there are two things going on with your MIDRANGE macro. First, it should be taking arguments, like you did with MIN. Ideally, it should take three arguments; after all, the whole reason to make it a macro is so that the macro user won't have to calculate everything. Second, if you want the result to be a floating-point number, you should divide by 2.0, not 2.
Here's my first suggestion:
#define MIDRANGE(A, B, C) ((MIN(MIN(A, B), C) + MAX(MAX(A, B), C)) / 2.0)
However, why is this a macro? Make it a function. It's more readable, and easier to mantain. So here's my second suggestion:
double midrange(int a, int b, int c)
{
int min = MIN(MIN(a, b), c);
int max = MAX(MAX(a, b), c);
return (min + max) / 2.0;
}
regarding:
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
#define MAX(A, B) {(A) > (B) ? (A) : (B);}
Lets remember that a macro is nothing more than a direct text replacement.
So looking at:
int min = MIN(MIN(a, b), c);
results in:
int min = { {(a) < (b) ? (a) : (b);} < (c);};
as is obvious from the above,
min is outside the braces '{' and '}' so will be difficult to assign to
the resulting statement contains two spurious ';' characters, which is what the compiler is complaining about
Suggest:
#define MIN( A, B ) ((A) < (B)) ? (A) : (B)
Similar considerations exist for the MAX macro
I have the following macro
#define POWER_OF_TW0(x) ( ((x) > 0) && (!((x)&((x) - 1))))
In order to make it misra compliant i tried
#define POWER_OF_TW0(x) ( ((x) > 0) && (!((unsigned)(x)&((unsigned)(x) - 1u))))
But this is still not misra compliant, because if the code is as below
uint8_t val = 4;
if(POWER_OF_TWO(val))
{
..
}
The misra tool will complain for unsigned number compared with signed number 0 ((x) > 0).
it will be happy if the declaration for val was signed e.g. int8_t.
I feel the only way out is to consider this macro will be given positive numbers and change the code to ((x) != 0u) i.e;
#define POWER_OF_TW0(x) ( ((x) != 0u) && (!((unsigned)(x)&((unsigned)(x) - 1u))))
Please let me know if there is an alternative solution.
Use a static inline function instead of a macro. (MISRA advises against "macro functions" anyway, see this SO question, so you should do that in any case.) Once it's an inline function you can type x as unsigned to avoid a lot of casting, as well as the > 0u issue.
C11 brings along with it _Generic which allows you to have macros that perform different actions based on the type passed into it. As an example with your POWER_OF_TWO, you could do something like this:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define POWER_OF_TWO(X) _Generic((X), \
uint8_t: ((X) != 0u) && (!((X)&((X) - 1u))), \
int8_t: ((X) > 0) && (!((X)&((X) - 1))) \
)
int main( void ){
uint8_t a = 2;
int8_t b = 2;
printf("%d\n", POWER_OF_TWO(a));
printf("%d\n", POWER_OF_TWO(b));
a++;
b++;
printf("%d\n", POWER_OF_TWO(a));
printf("%d\n", POWER_OF_TWO(b));
}
Or, incorporating the suggestions by Doug Currie and Lundin to use inline functions which is prefix/postfix safe:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
static inline _Bool power_of_two_int8(int8_t x) {
return (x > 0) && (!(x & (x - 1)));
}
static inline _Bool power_of_two_uint8(uint8_t x) {
return (x != 0u) && (!(x&(x - 1u)));
}
#define POWER_OF_TWO(X) _Generic((X), \
uint8_t: power_of_two_uint8((X)), \
int8_t: power_of_two_int8((X)) \
)
int main( void ){
uint8_t a = 2;
int8_t b = 2;
printf("%d\n", POWER_OF_TWO(a++));
printf("%d\n", POWER_OF_TWO(b++));
printf("%d\n", POWER_OF_TWO(a));
printf("%d\n", POWER_OF_TWO(b));
return EXIT_SUCCESS;
}
You can find more about _Generic at CppReference or in secition 6.5.1.1 of the C11 Standard draft.
FOOTNOTE
Lundin has pointed out in the comments that MISRA C:2012 does not yet support C11 as of 2018, so the following answer will unfortunately not satisfy MISRA compliance without a deviation.
UPDATE February 2021
MISRA C:2012 now supports some C11 language features. However, it states that type generic expressions are "prohibited without the support of a deviation against Rule 1.4".
writing leetcode
I use the macro like this:
#define max(a,b) ((a) > (b))?(a):(b)
it is wrong,when i change the macro like this,it's right
#define max(a,b) (((a) > (b))?(a):(b))
can't figure out why does this different.Here is the code,you can check it out.
#define UNBALANCED 99
#define max(a,b) (((a) > (b))?(a):(b))
int getHeight(struct TreeNode * root)
{
if(NULL == root)
return -1;
int l = getHeight(root->left);
int r = getHeight(root->right);
if(UNBALANCED == l || UNBALANCED == r || abs(l-r) > 1)
return UNBALANCED;
return 1 + max(l,r);
}
bool isBalanced(struct TreeNode* root)
{
if(NULL == root)
return true;
return getHeight(root) != UNBALANCED;
}
that is different with The need for parentheses in macros in C
The former fails to isolate the macro replacement from neighboring operands. For example:
1 + max(a, b)
expands to:
1 + ((a) > (b))?(a):(b)
and that groups as:
(1 + ((a) > (b))) ? (a) : (b)
Then (1 + ((a) > (b))) is always nonzero, so (a) is always chosen.
To prevent this, a macro that expands to an expression should use parenthesis around its entire expression to prevent its parts from grouping with neighboring operands.
The second version of your macro has extra parentheses which make the expression ((a) > (b))?(a):(b) evaluated as a whole. More code would be needed to explain exactly why the first one is wrong in your case. Also, see this.
Arguably both of them are incorrect; what if you wanted to use your macro like:
MAX(i++, j++)
The resulting ternary-operator expression from your examples cause whichever expression is smaller to be evaluated twice. Yowch! Since you (and most future readers) likely use GCC or clang, here's a better example with some compiler extensions (__typeof__ and statement expressions) that both of them support.
#define MAX(a, b) ({ __typeof__ (a) a__ = (a); \
__typeof__ (b) b__ = (b); \
(a__ > b__) ? a__ : b__; })
We all know this famous macro example:
#define max(a,b) ((a) > (b) ? (a) : (b))
And, since it uses a and b twice, it becomes inaccurate when we do something like:
max(x, y++); // because this gets translated to...
((x) > (y++) ? (x) : (y++)); // y is incremented twice
In Effective C++, Scott Meyers presents a C++ solution to this, using inline functions.
In 21st Century C, I was hoping for a similar C solution, but sadly all it advised was to avoid double usage. That made me sad. :'(
Of course, one can always replace it with a regular function. But I was wondering whether there is a C-only macro solution to this, that solves the double usage problem. Any possible solution?
In case of GCC you can use typeof extension, like this:
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
To your relief C has inline functions since C99.
I want to make a simple macro with #define for returning the smaller of two numbers.
How can i do this in C ? Suggest some ideas, and see if you can make it more obfuscated too.
Typically:
#define min(a, b) (((a) < (b)) ? (a) : (b))
Be warned this evaluates the minimum twice, which was the reason for disaster in a recent question.
But why would you want to obfuscate it?
This one stores the result in a variable, and only evaluates each argument once. It's basically a poor-mans inline function + declaration:
#define min(t, x, a, b) \
t x; \
{ \
t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
x = _this_is_a_unique_name_dont_use_it_plz_0_ < \
_this_is_a_unique_name_dont_use_it_plz_1_ ? \
_this_is_a_unique_name_dont_use_it_plz_0_ : \
_this_is_a_unique_name_dont_use_it_plz_1_ ; \
}
Use it like:
min(int, x, 3, 4)
/* x is an int, equal to 3
Just like doing:
int x = min(3, 4);
Without double evaluation.
*/
And, just for the hell of it, a GNU C example:
#define MAX(a,b) ({ \
typeof(a) _a_temp_; \
typeof(b) _b_temp_; \
_a_temp_ = (a); \
_b_temp_ = (b); \
_a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
})
It's not obfuscated, but I think this works for any type, in any context, on (almost, see comments) any arguments, etc; please correct if you can think of any counterexamples.
Sure, you can use a #define for this, but why would you want to? The problem with using #define, even with parentheses, is that you get unexpected results with code like this (okay, you wouldn't actually do this, but it illustrates the problem).
int result = min(a++, b++);
If you're using C++ not C, surely better to use an inline function, which (i) avoids evaluating the parameters more than once, and (ii) is type safe (you can even provide versions taking other types of value, like unsigned, double or string).
inline int min(int a, int b) { return (a < b) ? a : b; }
I think this method is rather cute:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
I want to make a simple macro with #define for returning the smaller of two numbers.
I wanted to add a solution when the numbers are floating point.
Consider when the numbers are floating point numbers and one of the numbers is not-a-number. Then the result of a < b is always false regardless of the value of the other number.
// the result is `b` when either a or b is NaN
#define min(a, b) (((a) < (b)) ? (a) : (b))
It can be desirable that the result is as below where "NaN arguments are treated as missing data". C11 Footnote #242
a NaN | b NaN | a < b | min
-------+---------+---------+---------------
No | No | No | b
No | No | Yes | a
No | Yes | . | a
Yes | No | . | b
Yes | Yes | . | either a or b
To do so with a macro in C would simple wrap the fmin() function which supprts the above table. Of course code should normally used the fmin() function directly.
#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))
Note that fmin(0.0, -0.0) may return 0.0 or -0.0. They both have equal value.
If I were just trying to lightly obfuscate this I would probably go with something like:
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
I think Doynax's solution is pretty cute, too. Usual reservations for both about macro arguments being evaluated more than once.
For slightly obfuscated, try this:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
Basically, it subtracts them, and looks at the sign-bit as a 1-or-0.
If the subtraction results in a negative number, the first parameter is smaller.