Misra compliant macro for Power of 2 in C - c

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".

Related

Can #define process arithmetic operations in preprocessing?

Can the C macro #define process arithmetic operations in preprocessing?
For example, if I write
#define A 1 + 1
will it be pre-processed to be equivalent to
#define A 2
before compiling?
Furthermore, is it possible to define constants this way without computation overhead:
#define A 1
#define B A + 1
#define C B + 1
...
?
Macros are text replacements (token replacements to be more accurate).
#define A 1 + 1
int main() { printf("%d\n", A); }
will expand to (run gcc -E on the source to get the preprocessor expansion)
int main() { printf("%d\n", 1 + 1); }
(which BTW, is why it's wise to heavily parenthesize in macros (#define A (1+1)), because
you'll usually want A*3 to then be 6 ( (1+1)*3 ) not 4 ( 1+1*3) ) ).
And yes 1+1, seeing as it satisfies the standard's rules for integer constant expressions, is pretty much guaranteed to be processed at compile time and so you can use it in contexts where an integer constant expression is required.
E.g.:
#define A (1+1)
extern char array[A] = { [A-1]='c' } ; //ICE required
struct s { int bitfield:A; }; //ICE required
enum { a = A }; //ICE required
int x = A; //ICE required
int main ()
{
switch(1) case A: puts("unreachable"); //ICE required
}

what is the difference of these two macro max?

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__; })

Is there a generic way to printf a variable?

If I have a macro like
#define MYMACRO(x) printf ("%any\n", x);
is there any %any formatter which can print anything, context-dependently?
Non-standard or GNU C specific are OK.
Update: Rewritten to focus more on the macro aspect.
If you limit yourself to a single argument, it's doable in C11 using generics. The linked-to page has an example, the gist of which is to use generics to map the type of the argument to the proper formatting string.
I don't want to "re-print" the entire blog post, but the macro begins:
#define printf_dec_format(x) _Generic((x), \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
/* more code deleted */
#define print(x) printf(printf_dec_format(x), x)
#define printnl(x) printf(printf_dec_format(x), x), printf("\n");
If you want to print the value of a numeric expression, without wanting to tell the compiler if it's signed or unsigned (i.e. without %u flags etc.) or if it's long, long long or whatever...
...then there's a way that works with old C standards also (C99, C90, ...).
Just use the macro P99_SIGNED from the find P99 project -- it also works for old C standards.
#include <stdio.h>
#include <limits.h> /* CHAR_BIT, LLONG_MIN, etc. */
/* http://p99.gforge.inria.fr/p99-html/group__integers_ga3eb39ccac28ebd8265c1a31dc00f53ab.html
P99 homepage: http://p99.gforge.inria.fr/
P99 repo: https://scm.gforge.inria.fr/anonscm/gitweb?p=p99/p99.git;a=tree
*/
#define P99_SIGN_PROMOTE(A, B) (1 ? (A) : (B))
#define P99_PROMOTE_0(EXPR) P99_SIGN_PROMOTE(0, (EXPR))
#define P99_PROMOTE_M1(EXPR) P99_SIGN_PROMOTE(-1, (EXPR))
#define P99_SIGNED(EXPR) (P99_PROMOTE_M1(EXPR) < P99_PROMOTE_0(EXPR))
#define print_num(x) (P99_SIGNED(x) \
? printf("%lld", ( signed long long)(x)) \
: printf("%llu", (unsigned long long)(x)))
int main()
{
print_num(-1); /* prints -1 */
putchar('\n');
print_num(1); /* prints 1 */
putchar('\n');
print_num(LLONG_MIN); /* prints -9223372036854775808 (dependant on archi) */
putchar('\n');
print_num(ULLONG_MAX); /* prints 18446744073709551615 (dependant on archi) */
putchar('\n');
return 0;
}
This can also be a big help in understanding integer promotion rules, since using e.g. print_num(-1+0U) you'll see that the compiler promotes all operands to unsigned (you get a large positive value!)
As has been mentioned by others: If you have a compiler that can handle C11 or newer: use _Generic -> Link. under the heading Printing values generically.

The best way to define a "between" macro in C

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))

Conditional Compilation and compile time evaluation of expressions in ANSI C

I would like to do the following, but the compiler doesn't like it:
unsigned short foo = 1;
// do something with foo
#if sizeof(short) * CHAR_BIT > 16
foo &= 0xffff;
#endif
I know this expression can always be fully evaluated at compile time, but maybe it's only evaluated after the preprocessor does it's thing? Is this possible in ANSI C or do I just have to do the check at run time?
You can't use sizeof in a preprocessor expression. You might want to do something like this instead:
#include <limits.h>
#if SHRT_MAX > 32767
/* do soemthing */
#endif
If your aim is to stop compilation when a data type is the wrong size, the following technique is useful:
struct _check_type_sizes
{
int int_is_4_bytes[(sizeof(int) == 4) ? 1 : -1];
int short_is_2_bytes[(sizeof(short) == 2) ? 1 : -1];
};
(The sizeof() function is interpreted here by the compiler, not the preprocessor.)
The main disadvantage of this method is that the compiler error isn't very obvious. Make sure you write a very clear comment.

Resources