How do I tell if a C integer variable is signed? - c

As an exercise, I'd like to write a macro which tells me if an integer variable is signed. This is what I have so far and I get the results I expect if I try this on a char variable with gcc -fsigned-char or -funsigned-char.
#define ISVARSIGNED(V) (V = -1, (V < 0) ? 1 : 0)
Is this portable? Is there a way to do this without destroying the value of the variable?

#define ISVARSIGNED(V) ((V)<0 || (-V)<0 || (V-1)<0)
doesn't change the value of V. The third test handles the case where V == 0.
On my compiler (gcc/cygwin) this works for int and long but not for char or short.
#define ISVARSIGNED(V) ((V)-1<0 || -(V)-1<0)
also does the job in two tests.

If you're using GCC you can use the typeof keyword to not overwrite the value:
#define ISVARSIGNED(V) ({ typeof (V) _V = -1; _V < 0 ? 1 : 0 })
This creates a temporary variable, _V, that has the same type as V.
As for portability, I don't know. It will work on a two's compliment machine (a.k.a. everything your code will ever run on in all probability), and I believe it will work on one's compliment and sign-and-magnitude machines as well. As a side note, if you use typeof, you may want to cast -1 to typeof (V) to make it safer (i.e. less likely to trigger warnings).

#define ISVARSIGNED(V) ((-(V) < 0) != ((V) < 0))
Without destroying the variable's value. But doesn't work for 0 values.
What about:
#define ISVARSIGNED(V) (((V)-(V)-1) < 0)

This simple solution has no side effects, including the benefit of only referring to v once (which is important in a macro). We use the gcc extension "typeof" to get the type of v, and then cast -1 to this type:
#define IS_SIGNED_TYPE(v) ((typeof(v))-1 <= 0)
It's <= rather than just < to avoid compiler warnings for some cases (when enabled).

A different approach to all the "make it negative" answers:
#define ISVARSIGNED(V) (~(V^V)<0)
That way there's no need to have special cases for different values of V, since ∀ V ∈ ℤ, V^V = 0.

A distinguishing characteristic of signed/unsigned math is that when you right shift a signed number, the most significant bit is copied. When you shift an unsigned number, the new bits are 0.
#define HIGH_BIT(n) ((n) & (1 << sizeof(n) * CHAR_BITS - 1))
#define IS_SIGNED(n) (HIGH_BIT(n) ? HIGH_BIT(n >> 1) != 0 : HIGH_BIT(~n >> 1) != 0
So basically, this macro uses a conditional expression to determine whether the high bit of a number is set. If it's not, the macro sets it by bitwise negating the number. We can't do an arithmetic negation because -0 == 0. We then shift right by 1 bit and test whether sign extension occurred.
This assumes 2's complement arithmetic, but that's usually a safe assumption.

Why on earth do you need it to be a macro? Templates are great for this:
template <typename T>
bool is_signed(T) {
static_assert(std::numeric_limits<T>::is_specialized, "Specialize std::numeric_limits<T>");
return std::numeric_limits<T>::is_signed;
}
Which will work out-of-the-box for all fundamental integral types. It will also fail at compile-time on pointers, which the version using only subtraction and comparison probably won't.
EDIT: Oops, the question requires C. Still, templates are the nice way :P

Related

What double negation does in C

I had a controversy about what compilers "think" about this:
a = 8;
b = !!a;
So, is b == 0x01 ? Is TRUE always 0x01 or it may be 0xFF, 0xFFFF, 0xFFFFFFFF etc..?
If I want to extract only 0x00 if (a == 0) and 0x01 if (a > 0) does this double negation approach works?
In other words: to obtain result only 0 or 1, what is better to use?
a) a>0?1:0;
b) !!a
I hope you understand my question.
You have not supplied enough information to tell whether !!a works for your purposes or not.
You stated that you really need the result of a > 0. However, this is not equivalent to !!a if a is signed and holds a negative value. If this is possible, then the answer is obviously "no".
!!a is equivalent to a != 0, not to a > 0.
Yes, b == 1. The result of any boolean operator is always 0 or 1. You can do better though...
I want to extract only 0x00 if (a == 0) and 0x01 if (a > 0)
b = a > 0; most accurately reflect your rule.
!!a will be either 0 or 1, and will be type int. It will be 0 for zero a, and 1 otherwise.
As for your choices (a) and (b), they are not equivalent, due to a possibility of a being negative. That aside, you could argue that a > 0 ? 1 : 0 is clearer but in performance-critical applications !!a may be better as it will not branch whereas a ternary conditional could dump the pipeline. But a good compiler will optimise out either way. I seldom use either since things like if (a) and if (!!a) are functionally equivalent.
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E). C11 §6.5.3.3 5
b below will typical have the value of 1 (or possible -1, see below).
a = 8;
b = !!a;
So, is b == 0x01?
Yes (* see below)
Is TRUE always 0x01 or it may be 0xFF, 0xFFFF, 0xFFFFFFFF etc..?
In <stdbool.h>, true is a macro with the integer constant 1. TRUE is not defined by the C standard. Various implementations defines it with the value of 1. It might be have other values. It certainly should be non-zero.
what is better to use?
A) a>0?1:0
B) !!a
Both result in an int with the value of 0 or 1. A reasonable to good compiler would be expected to generate the same code for both (if a in not signed). Use the form that 1) adhere to your groups coding standard or else 2) best conveys the meaning of code at that point. A third option which results in type (bool):
C) (bool) a
If a is signed , then a>0?1:0 is not equivalent to !!a. a != 0 ? 1 :0 is equivalent of !!a.
* If b is a 1 bit signed bit field, b = !!8 will have the value of -1.
In teems of speed I think this is highly dependent on the compiler and processor you are using.
The longer expression would produce an executable 4 - 16 bytes larger.

C programming: testing oversized shift

Negative and oversized bit shifts are undefined behaviour. But I need to do positive/negative shifts in many places of my code, so I wrote a generic function for that:
uint64_t shift_bit(uint64_t b, int i)
{
// detect oversized shift
assert(-63 <= i && i <= 63);
return i >= 0 ? b << i : b >> -i;
}
That takes care of negative shifts. But what about oversized shift?
Is a C compiler allowed to optimize away the assert()? (Or to replace it with assert(true), which has the same effect).
Is there a way to code around it?
PS: Please base your answers only on what the standard guarantees, not on what your specific compiler does. My program needs to be 100% portable, as it gets compiled for many different platforms, and with many different compilers.
assert() is replaced to "nothing" on release.
#ifdef NDEBUG
#define assert(exp) ((void)0)
#else
#define assert(exp) /*implementation*/
#endif

How to toggle an int / _Bool in C

Suppose we have an int and want to toggle it between 0 and 1 in a boolean fashion. I thought of the following possibilities:
int value = 0; // May as well be 1
value = value == 0 ? 1 : 0;
value = (value + 1) % 2;
value = !value; // I was curious if that would do...
The third one seems to work. Why? Who decides that !0 is 1?
Is something wrong with any of these?
Are there other possibilities? e.g. bitwise operators?
Which offers the best performance?
Would all that be identical with _Bool (or bool from stdbool.h)? If not, what are the differences?
EDIT: Many great answers with lots of valuable information, thanks! Unfortunately, I can only accept one.
value = !value; expresses what you want to do directly, and it does exactly what you want to do by definition.
Use that expression.
From C99 6.5.3.3/5 "Unary arithmetic operators":
The result of the logical negation operator ! is 0 if the value of its
operand compares unequal to 0, 1 if the value of its operand compares
equal to 0. The result has type int. The expression !E is equivalent
to (0==E).
The third one seems to work. Why? Who decides that !0 is 1?
C Standard guarantees that !0 is 1.
Are there other possibilities? e.g. bitwise operators?
Yes, you can use the exclusive OR operator:
value ^= 1;
By the way I prefer this to value = !value; as relational and equality operators can result to branching and bitwise operators usually do not.
value = 1 - value; // toggle from 0 to 1 ... or 1 to 0
// when you know initial value is either 0 or 1
the language was designed that way.
Use the 3rd one, the others are right but unnecessarly complicated and therefore hiding the intent.
value = (value ^ 1) & 1;
They're all the same after optimisation.
_Bool would have the same results. The only thing different with _Bool is that values are coerced to be either 1 or 0. Meaning that bool x = 55; will have the value x == 1
EDIT: Corrected the formula in 3 because of my brainfart. I let the comments so that people can see my blooper.
value = !value seems the most reasonable one, but you can also use value = 1 - value or value ^= 1. But the last two would both break if value is not 0 or 1. The first one would still work.
There can be noticeable performance issues with the alternatives depending on the architecture:
!a might need in some architectures comparison and branching, which can be expensive depending on the pattern of 'a'
on some architectures there is conditional move (which is branchless), but
which may require still 3 instructions to complete (with dependencies)
1-a most likely needs two instructions in many architectures
counter example: ARM has reverse subtraction RSB %r0, %r0, #1
1^a can be implemented in many architecture with a single instruction
a=(a+1) % 2 will be most likely optimized to a=(a+1)&1, which requires 2 instructions
But anyway the first rule of optimization is that don't optimize a non working code.
To replace !a with a^1, one has to be 100% certain that it produces always the expected value.
Your expression value = value == 0 ? 1 : 0; will work exactly like value = !value;. You can use any of the two.
!0 is always 1 and also !(any non zero value) is 0
Use bitwise NOT operator
var = ~var;

Can the C preprocessor perform integer arithmetic?

As the questions says, is the C preprocessor able to do it?
E.g.:
#define PI 3.1416
#define OP PI/100
#define OP2 PI%100
Is there any way OP and/or OP2 get calculated in the preprocessing phase?
Integer arithmetic? Run the following program to find out:
#include "stdio.h"
int main() {
#if 1 + 1 == 2
printf("1+1==2\n");
#endif
#if 1 + 1 == 3
printf("1+1==3\n");
#endif
}
Answer is "yes", there is a way to make the preprocessor perform integer arithmetic, which is to use it in a preprocessor condition.
Note however that your examples are not integer arithmetic. I just checked, and gcc's preprocessor fails if you try to make it do float comparisons. I haven't checked whether the standard ever allows floating point arithmetic in the preprocessor.
Regular macro expansion does not evaluate integer expressions, it leaves it to the compiler, as can be seen by preprocessing (-E in gcc) the following:
#define ONEPLUSONE (1 + 1)
#if ONEPLUSONE == 2
int i = ONEPLUSONE;
#endif
Result is int i = (1 + 1); (plus probably some stuff to indicate source file names and line numbers and such).
The code you wrote doesn't actually make the preprocessor do any calculation. A #define does simple text replacement, so with this defined:
#define PI 3.1416
#define OP PI/100
This code:
if (OP == x) { ... }
becomes
if (3.1416/100 == x) { ... }
and then it gets compiled. The compiler in turn may choose to take such an expression and calculate it at compile time and produce a code equivalent to this:
if (0.031416 == x) { ... }
But this is the compiler, not the preprocessor.
To answer your question, yes, the preprocessor CAN do some arithmetic. This can be seen when you write something like this:
#if (3.141/100 == 20)
printf("yo");
#elif (3+3 == 6)
printf("hey");
#endif
YES, I mean: it can do arithmetic :)
As demonstrated in 99 bottles of beer.
Yes, it can be done with the Boost Preprocessor. And it is compatible with pure C so you can use it in C programs with C only compilations. Your code involves floating point numbers though, so I think that needs to be done indirectly.
#include <boost/preprocessor/arithmetic/div.hpp>
BOOST_PP_DIV(11, 5) // expands to 2
#define KB 1024
#define HKB BOOST_PP_DIV(A,2)
#define REM(A,B) BOOST_PP_SUB(A, BOOST_PP_MUL(B, BOOST_PP_DIV(A,B)))
#define RKB REM(KB,2)
int div = HKB;
int rem = RKB;
This preprocesses to (check with gcc -S)
int div = 512;
int rem = 0;
Thanks to this thread.
Yes.
I can't believe that no one has yet linked to a certain obfuscated C contest winner. The guy implemented an ALU in the preprocessor via recursive includes. Here is the implementation, and here is something of an explanation.
Now, that said, you don't want to do what that guy did. It's fun and all, but look at the compile times in his hint file (not to mention the fact that the resulting code is unmaintainable). More commonly, people use the pre-processor strictly for text replacement, and evaluation of constant integer arithmetic happens either at compile time or run time.
As others noted however, you can do some arithmetic in #if statements.
Be carefull when doing arithmetic: add parenthesis.
#define SIZE4 4
#define SIZE8 8
#define TOTALSIZE SIZE4 + SIZE8
If you ever use something like:
unsigned int i = TOTALSIZE/4;
and expect i to be 3, you would get 4 + 2 = 6 instead.
Add parenthesis:
#define TOTALSIZE (SIZE4 + SIZE8)

How to neatly avoid C casts losing truth

I'm quite happy that, in C, things like this are bad code:
(var_a == var_b) ? TRUE : FALSE
However, what's the best way of dealing with this:
/* Header stuff */
#define INTERESTING_FLAG 0x80000000
typedef short int BOOL;
void func(BOOL);
/* Code */
int main(int argc, char *argv[])
{
unsigned long int flags = 0x00000000;
... /* Various bits of flag processing */
func(flags & INTERESTING_FLAG); /* func never receives a non-zero value
* as the top bits are cut off when the
* argument is cast down to a short
* int
*/
}
Is it acceptable (for whatever value of acceptable you're using) to have (flags & FLAG_CONST) ? TRUE : FALSE?
I would in either case called func with (flags & INTERESTING_FLAG) != 0 as an argument to indicate that a boolean parameter is required and not the arithmetic result of flags & INTERESTING_FLAG.
I'd prefer (flags & CONST_FLAG) != 0. Better still, use the _Bool type if you have it (though it's often disguised as bool).
Set your compiler flags as anally as possible, to warn you of any cast that loses bits, and treat warnings as errors.
Some people don't like it, but I use !!.
ie
!!(flags & CONST_FLAG)
(not as a to_bool macro as someone else suggested, just straight in the code).
If more people used it, it wouldn't be seen as unusual so start using it!!
This may not be a popular solution, but sometimes macros are useful.
#define to_bool(x) (!!(x))
Now we can safely have anything we want without fear of overflowing our type:
func(to_bool(flags & INTERESTING_FLAG));
Another alternative might be to define your boolean type to be an intmax_t (from stdint.h) so that it's impossible for a value to be truncated into falseness.
While I'm here, I want to say that you should be using a typedef for defining a new type, not a #define:
typedef short Bool; // or whatever type you end up choosing
Some might argue that you should use a const variable instead of a macro for numeric constants:
const INTERESTING_FLAG = 0x80000000;
Overall there are better things you can spend your time on. But macros for typedefs is a bit silly.
You could avoid this a couple different ways:
First off
void func(unsigned long int);
would take care of it...
Or
if(flags & INTERESTING_FLAG)
{
func(true);
}
else
{
func(false);
}
would also do it.
EDIT: (flags & INTERESTING_FLAG) != 0 is also good. Probably better.
This is partially off topic:
I'd also create a help function that makes it obvious to the reader what the purpose of the check is so you don't fill your code with this explicit flag checking all over the place. Typedefing the flag type would make it easier to change flag type and implementation later.
Modern compilers supports the inline keyword that can get rid of the performance overhead in a function call.
typedef unsigned long int flagtype;
...
inline bool hasInterestingFlag(flagtype flags) {
return ((flags & INTERESTING_FLAG) != 0);
}
Do you have anything against
flags & INTERESTING_FLAG ? TRUE : FALSE
?
This is why you should only use values in a "boolean" way when these values have explicitly boolean semantics. Your value does not satisfy taht rule, since it has a pronounced integer semantics (or, more precisely, bit-array semantics). In order to convert such a value to boolean, compare it to 0
func((flags & INTERESTING_FLAG) != 0);

Resources