PDA

View Full Version : [SOLVED] Boolean variables in C



crazyfuturamanoob
January 10th, 2009, 08:34 PM
I want a boolean variable, which needs only 1 bit memory,
and can have either 1 or 0 as value, of course.

But C doesn't have a boolean variable by default, so how to make one?

jimi_hendrix
January 10th, 2009, 08:36 PM
a)



#import <boolean.h>


b)



enum bool = {false, true};


c)



#define bool int
#define true 1
#define false 0


should all work

SledgeHammer_999
January 10th, 2009, 08:42 PM
Of course C has built-in boolean variables

bool var;
var = false;
var = true;

In this example var is 1 byte in size.

jimi_hendrix
January 10th, 2009, 08:45 PM
not ANSI C iirc...what C are you useing?!?!

Bachstelze
January 10th, 2009, 08:46 PM
Of course C has built-in boolean variables

bool var;
var = false;
var = true;

In this example var is 1 byte in size.

No it doesn't.


firas@itsuki ~ % cat bool.c
int main(void)
{
bool var;
var = true;
return 0;
}

firas@itsuki ~ % cc -o bool bool.c
bool.c: In function 'main':
bool.c:3: error: 'bool' undeclared (first use in this function)
bool.c:3: error: (Each undeclared identifier is reported only once
bool.c:3: error: for each function it appears in.)
bool.c:3: error: expected ';' before 'var'
bool.c:4: error: 'var' undeclared (first use in this function)
bool.c:4: error: 'true' undeclared (first use in this function)

mali2297
January 10th, 2009, 08:49 PM
a)



#import <boolean.h>



Rather...


#include <stdbool.h>

bool b = false;

jimi_hendrix
January 10th, 2009, 08:53 PM
havnt had a need to use the lib in a while...thanks

dwhitney67
January 10th, 2009, 09:39 PM
havnt had a need to use the lib in a while...thanks
:confused: What lib are you referring to?

jimi_hendrix
January 10th, 2009, 09:43 PM
*fails at vocab*
the header

monkeyking
January 10th, 2009, 09:49 PM
I want a boolean variable, which needs only 1 bit memory,
and can have either 1 or 0 as value, of course.

But C doesn't have a boolean variable by default, so how to make one?

It's quite impossible to have 1bit variables as primitive types in c/c++.

The smallest amount of memory you can access directly is a byte,
this is defined as the size of a char by CHAR_BIT.

If you still want this lowmemory variable you can still implement it by extracting and shifting bitpatterns.

If you use c++
then you can use vector<bool> which will try to pack it and spaceoptimize.

The vector<bool> type is very different from the other vector<T> types. http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98

good luck

Cracauer
January 10th, 2009, 10:24 PM
You can't have one variable that only occupies one bit.


You can have a bunch of variables each occupying one bit two ways:

structs with bit width field



struct {
int blah: 1;
int fasel: 1;
int blubb: 1;
};


Or you can manually pack them into a bit-vector of your choice (usually operates on a long int).

SledgeHammer_999
January 10th, 2009, 10:26 PM
No it doesn't.


firas@itsuki ~ % cat bool.c
int main(void)
{
bool var;
var = true;
return 0;
}

firas@itsuki ~ % cc -o bool bool.c
bool.c: In function 'main':
bool.c:3: error: 'bool' undeclared (first use in this function)
bool.c:3: error: (Each undeclared identifier is reported only once
bool.c:3: error: for each function it appears in.)
bool.c:3: error: expected ';' before 'var'
bool.c:4: error: 'var' undeclared (first use in this function)
bool.c:4: error: 'true' undeclared (first use in this function)


I FAIL! hahahaha
I was under the impression that it has "bool". I have been using till today C++ and I thought that this fundamental type was available in C too... I guess I was totally wrong.

jimi_hendrix
January 10th, 2009, 10:30 PM
hehe...for loops are different too...cant declare a new var in the for () part...only assign a value

snova
January 10th, 2009, 11:09 PM
There is a _Bool type.

jimi_hendrix
January 10th, 2009, 11:31 PM
since when?

dwhitney67
January 10th, 2009, 11:42 PM
I FAIL! hahahaha
I was under the impression that it has "bool". I have been using till today C++ and I thought that this fundamental type was available in C too... I guess I was totally wrong.

This was what I thought too, but I was proven wrong.

If you want the 'bool' type in a C program, #include <stdbool.h>.

dwhitney67
January 10th, 2009, 11:43 PM
hehe...for loops are different too...cant declare a new var in the for () part...only assign a value

That is because you are probably using the ISO C standard adopted in the stone-ages. Use a more current version (e.g. 1999 standards), then you can declare variables in C at the closest point where needed.

snova
January 11th, 2009, 12:06 AM
since when?

Since I tried it, at the least. :P

test.c:


int main()
{
_Bool b;
return 0;
}


gcc -o test test.c

No problems here...

jespdj
January 11th, 2009, 12:42 AM
I don't know where that _Bool type comes from, but it is certainly not standard C.

C has bit fields (http://en.wikipedia.org/wiki/Bit_field), that's the closest you can come to a boolean that takes only 1 bit of memory space.

samjh
January 11th, 2009, 12:49 AM
_Bool is part of the C99 standard, contained in stdbool.h.

jimi_hendrix
January 11th, 2009, 12:56 AM
That is because you are probably using the ISO C standard adopted in the stone-ages. Use a more current version (e.g. 1999 standards), then you can declare variables in C at the closest point where needed.

i just use what gcc says...how do i use C99 (i thought it wasnt ansi)

wmcbrine
January 11th, 2009, 03:03 AM
Bit fields are unreliable (their representation may vary), and yes, the bool type is only in C99 (C89 is still the de facto standard), and wouldn't do what you want anyway.

The normal way to handle this in C is to use the bitwise operators to arrange multiple boolean flags into a char, int or long. For example:



#define MASK_FOO 1
#define MASK_BAR 2 /* next would be 4, 8, etc. */

unsigned char flags = 3;

if (flags & MASK_BAR)
printf("Bar is set!\n");

flags &= ~(MASK_FOO); /* unset foo */


Etc.

jpkotta
January 11th, 2009, 06:24 AM
In C, any value that isn't equal to 0 is true. This goes for pointers, numeric types, enums, floats, etc. structs can't be compared so they don't count.

To alias a value to 0 or 1, you can apply logical not twice:


int bool = !!(bitvector & MASK); /* bool is 0 or 1 */

PmDematagoda
January 11th, 2009, 07:56 AM
_Bool is part of the C99 standard, contained in stdbool.h.

_Bool is part of C99, but it is not contained in stdbool.h, stdbool.h contains the bool type. stdio.h has _Bool, and _Bool can have either 0 or 1.

PmDematagoda
January 11th, 2009, 08:08 AM
i just use what gcc says...how do i use C99 (i thought it wasnt ansi)

GCC can use _Bool, I've used it plenty of times with only the stdio.h header. And you don't need to tell it to use a specific type of standard either. And, correct me if I'm wrong, but isn't C99 the new ANSI/ISO standard for C?

mdurham
January 11th, 2009, 08:09 AM
To alias a value to 0 or 1, you can apply logical not twice:


int bool = !!(bitvector & MASK); /* bool is 0 or 1 */

V Clever

Npl
January 11th, 2009, 08:13 AM
GCC can use _Bool, I've used it plenty of times with only the stdio.h header. And you don't need to tell it to use a specific type of standard either. And, correct me if I'm wrong, but isn't C99 the new ANSI/ISO standard for C?
Well, theres no reason to use _Bool. just include stdbool.h which will work transparently with all C Versions.

AFAIK all recent C Versions are ISO-Standards, very very long ago it was an ANSI standard. ANSI-C denotes the stone-old Version at any rate, and theres little reason to use it.

Npl
January 11th, 2009, 08:15 AM
In C, any value that isn't equal to 0 is true. This goes for pointers, numeric types, enums, floats, etc. structs can't be compared so they don't count.

To alias a value to 0 or 1, you can apply logical not twice:


int bool = !!(bitvector & MASK); /* bool is 0 or 1 */

Its more efficient to compare against 0:

int bool = (bitvector & MASK) != 0;

PmDematagoda
January 11th, 2009, 08:51 AM
Well, theres no reason to use _Bool. just include stdbool.h which will work transparently with all C Versions.

AFAIK all recent C Versions are ISO-Standards, very very long ago it was an ANSI standard. ANSI-C denotes the stone-old Version at any rate, and theres little reason to use it.

Even though there may not be much of a reason to use _Bool, you can use it, that's just it:).

crazyfuturamanoob
January 11th, 2009, 09:35 AM
Looks like it's just easier to use integers for this. :S

samjh
January 11th, 2009, 10:00 AM
Looks like it's just easier to use integers for this. :S

You are correct. :)

Even stdbool's booleans are just typedefs and macros. Nothing special. IMHO, it's of no use except to enhance readability.

wmcbrine
January 11th, 2009, 11:10 AM
ANSI-C denotes the stone-old Version at any rate, and theres little reason to use it.ANSI C is old, but it's nowhere near as old as "K & R" C (so named because it's defined by the first edition of the K & R book, rather than by a standards committee). That's the "old version".

ANSI C, aka C89, is the most widely-implemented version of the language, and it's still the standard that gcc defaults to. You have to give gcc an option to tell it to use C99 -- and in fact, C99 is not quite fully supported even now. So yes, there's good reason to use ANSI C.

But there's no longer much reason to use K & R C, which is the one where functions look like this:



foo(a, b)
int a;
int b;
{
...


instead of:



int foo(int a, int b)
{
...

Cracauer
January 11th, 2009, 02:44 PM
The original poster explicitly said he wants one that takes up one bit (presumably when combined with other bools).

So C99's bool is out.

In C++ they decided to kick out explicit bit-vectors in favor of telling the user to hope that vector<bool> will be specialized to a bit-fiddling facility. Sometimes I don't get these people...

jpkotta
January 12th, 2009, 03:53 AM
Its more efficient to compare against 0:

int bool = (bitvector & MASK) != 0;

Not always. I'm not sure if this is ever the case. They compile to the same thing for me (I only tested on one machine, with and without -O2), and this is exactly what I would expect for any decent compiler.


#include <stdint.h>
#define MASK (1<<10)

int double_negative(uint32_t bv)
{
return !!(bv & MASK);
}

int cmp_zero(uint32_t bv)
{
return (bv & MASK) != 0;
}


gcc bool.c -c
objdump -d bool.o


00000000 <double_negative>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 08 mov 0x8(%ebp),%eax
6: 25 00 04 00 00 and $0x400,%eax
b: 85 c0 test %eax,%eax
d: 0f 95 c0 setne %al
10: 0f b6 c0 movzbl %al,%eax
13: 5d pop %ebp
14: c3 ret

00000015 <cmp_zero>:
15: 55 push %ebp
16: 89 e5 mov %esp,%ebp
18: 8b 45 08 mov 0x8(%ebp),%eax
1b: 25 00 04 00 00 and $0x400,%eax
20: 85 c0 test %eax,%eax
22: 0f 95 c0 setne %al
25: 0f b6 c0 movzbl %al,%eax
28: 5d pop %ebp
29: c3 ret

So it all comes down to which is more readable. Personally, I think mine is, but I'm biased. Obviously it doesn't really matter, because you could make a macro that implements either one.


#define BOOLIFY1(x) (!!(x))
#define BOOLIFY2(x) ((x) != 0)