Double boolean negation operator [duplicate] - c++

This question already has answers here:
Double Negation in C++
(14 answers)
double negation in C : is it guaranteed to return 0/1?
(2 answers)
Closed 5 years ago.
I came across this piece of code from the Microsoft implementation of GSL (the C++ Guideline Support Library):
#if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define GSL_LIKELY(x) (!!(x))
#define GSL_UNLIKELY(x) (!!(x))
#endif
I read about the __builtin_expect (here and here), but it is still unclear to me what is the purpose of the double boolean negation operator in (!!(x)). Why is it used?
The file in question is this one.

__builtin_expect works with strict equality, so the point of double negation here is to make sure all truthy values are converted to 1 (and thus match the 1 in GSL_LIKELY), and all the falsy values match the 0 in GSL_UNLIKELY.
The double negation is kept even if __builtin_expect is not available to keep uniformity (as the caller may store the return value for other uses besides as a condition in an if).

Related

How to get C compiler #error if a sizeof(struct ...) not equal to a given number? [duplicate]

This question already has answers here:
How can I use "sizeof" in a preprocessor macro?
(13 answers)
Closed 3 years ago.
How to get C compile time #error if a sizeof(struct ...) not equal to a given number?
The question is from programming course, where I'd like to avoid to run miss-sized binary code.
(The sizeof operator, as we know, doesn't work in #if .. #endif directive.)
How to get C compile time #error if a sizeof(struct ...) not equal to a given number?
You cannot, because the pre-processor knows nothing about sizes of types.
You can however static_assert:
static_assert(sizeof(T) == N, "T must have size N")
In C, the keyword is _Static_assert, also available through macro static_assert in <assert.h>.
Don't. You already explained why.
In modern C++ you can write:
static_assert(sizeof(T) == 42);
Although it is better to write code that doesn't care what the size of T is.
#include <assert.h>
//T should have size 10
static_assert(sizeof(T) == 10)
It's available only the latest C compiler

Does "&" vs. "&&" actually make a difference for compile-time flags?

I have a habit of using the following syntax in my compile-time flags:
#if (defined(A) & defined(B))
It's usually suggested that I do it with the && as follows:
#if (defined(A) && defined(B))
I know the difference between the two operators, and that in normal code && would short-circuit. However, the above is all handled by the compiler. Does it even matter what I use? Does it affect compile time by some infinitesimal amount because it doesn't evaluate the second define()?
Since defined(SOMETHING) yields 0 or 1, so that you're guaranteed 0 or 1 on both sides, it doesn't make a technical difference whether you use & or &&.
It's mostly about good habits (using & could carry over to some situation where it would be wrong) and about writing code that is easy to grasp by simple pattern matching. A & in there causes a millisecond pause while one considers whether it possibly could be a bit-level thing.
On the third hand, you can't use keyword and, which you ¹can use in ordinary C++ code.
Notes:
¹ With Visual C++ you can use and via a forced include of <iso646.h>.
According to the C99 standard, the expressions used in the preprocessor are constant expressions as defined by the C language itself, and are evaluated using the same engine. Therefore, && is a logical and operator that short circuits based on its LHS, and & is a bitwise operator with no predefined order of evaluation.
In practical terms, when used with defined() as you are, there is no difference between the two. However, the following would show a difference:
#define A 2
#define B 5
#if (A && B)
printf("A && B\n");
#endif
#if (A & B)
printf("A & B"\n);
#endif
In this case, A && B will be output, but not A & B (since the result of that bitwise-and is 0)
I would like to add to the previous answers that it can actually matter a lot in a situation like this:
#define A 0
#define B 21
#if (A != 0) && (42 / A == B)
/* ... */
#endif
Here, if A == 0, the compiler will not break. Writing (A != 0) & (42 / A == B) will make the compiler complain about a division by zero.

Can a MACRO be compared in #if with non numeric value [duplicate]

This question already has answers here:
How to compare strings in C conditional preprocessor-directives
(14 answers)
Closed 6 years ago.
consider the following
#if TABLE_SIZE>200
#undef TABLE_SIZE
#define TABLE_SIZE 200
The macro TABLE_SIZE is being compared
is it possible that its compared with a non numeric value like,
#if MACRO==ABCDEF123
I tried it but compiler complains of ABCDEF123 not being defined and assumes it as 0.
For true portability, the expression in #IF expression can only contain integer and character constants. The C and C++ preprocessors can also evaluate +, -, *, /, <<, >>, !=, == and the two logical operators && and || which obey the short-circuiting rules of standard C and C++.
So no, you can't compare a string directly.

Confused by squaring macro SQR in c [duplicate]

This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Confusion with Macro expansion [duplicate]
(3 answers)
Closed 9 years ago.
This question was asked to me in a mock interview...Really got surprised to find awkward answers...
consider a macro:
#define SQR(x) (x*x)
Example 1:
SQR(2) //prints 4
Example 2:
If SQR(1+1) is given it doesn't sum (1+1) to 2 but rather ...
SQR(1+1) //prints 3
Awkward right? What is the reason? How does this code work?
NOTE: I searched SO but couldn't find any relevant questions. If there are any kindly please share it!
SQR(1+1) expands to 1+1*1+1 which is 3, not 4, correct?
A correct definition of the macro would be
#define SQR(x) ((x)*(x))
which expands to (1+1)*(1+1) and, more important, shows you one of the reasons you shouldn't use macros where they aren't needed. The following is better:
inline int SQR(int x)
{
return x*x;
}
Furthermore: SQR(i++) would be undefined behavior if SQR is a macro, and completely correct if SQR is a function.
The problem is that macros are doing textual substition before it is compiled, so the macro expands to 1+1*1+1
That is why you always put arguments to macros into ():
#define SQR(x) ((x)*(x))

What is the usage of "!!" (negating twice)? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Double Negation in C++ code
Let's say:
bool var = !!true;
It will assign "true" to the variable. Seems useless, but I was looking at Visual Studio's definition of "assert", and it is:
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
Why does it negate the "_Expression" twice?
I wonder that they want to force the "!" operator to be called (in the case it is overloaded), but that doesn't seem to be a good reason.
!! guarantees that the result will end up as a 1 or a 0, rather than just the value of _Expression or 0. In C, it's unlikely to matter, but in C++ I think it turns the result of the expression into a bool type, which might be useful in some cases. If you did have some API that required a literal 1 or 0 be passed to it, using !! would be a way to make it happen.
It's possible that you might want an int variable that's either 1 or 0.
So you can't for example pass a 5, instead the double negation would turn that 5 into a 1.
Also, have a look at how TRUE is defined:
#ifndef TRUE
#define TRUE 1
#endif
Therefore, an expression like:
int x = 5;
if ( x == TRUE )
{
//....
}
would not pass, whereas
if ( x )
{
//....
}
would.
Its use is to make sure the value is either 0 or 1. I think it's superfluous with C++'s bool type.