# Thread: Could someone explain this code for me please...

1. lol yeah it's long. I edited after your post, that's why. Like I said, it took me so long to explain it. Oh by the way, if you set a value to one of the ints that takes more than 8 bits, it'll set the first 8 bits of the number, and leave the other 3 bytes in memory untouched. For example, if you set one of the numbers to 400, which is 110010000 in binary(9 bits), it'll set the first 8 bits, 10010000, and chop off any extra(the leftmost 1 in this case) because it will not go out of bounds. So it'll leave you with the 8 bits 10010000 as your number, which in decimal is 144.

2. Lol, thats pretty interesting and sweet, nice job guys~

I'm not sure I see the point of seperating a struct into 4 ints that only store 1 byte each, therefor the struct is the size of an int.. but maybe thats because I decided to wait before I get into the bitshifting tutorial. Theres probably some bitwise operation that you can use that makes it uber efficient

However, I cant even get "unsigned int zero:8;" line to compile.

3. Post in the whole program, it's probably another line that's doing it. I've been working with Java for a while, which is similar to C++ so I know a lot of stuff already, things like pointers, references, etc (as you can see in my other post) I'm not as familiar with and I need some help with. But I'm pretty experienced with Java, which has the same bitwise operators as C++, which and extra >>> infact, so regardless, I could do that in either language, so it was easy after reading a lot on CProgramming, and knowing Java previously. Also, with the struct, you don't use any bitshifting with it, it does it by itself automatically. Basically that example program I posted is what's going on in that struct with the number, except it's not assigning them to other ints.

4. I did the simpliest program I could to get it to work, no dice. However I am tired so who knows what I'm doing wrong.

Code:
```#include <iostream>

using namespace std;

int main()
{
unsigned int zero:8;
cout << zero << endl;

zero = 500;
cout << zero << endl;
}```

5. Syntax-wise it looks fine, but I believe you need to have the variable within a struct for it to work. Like I said, it seems to be used to compress the size of a struct if you don't need more than whatever bits. Try compiling this:
Code:
```#include <iostream>
using namespace std;

struct compressed {
usigned int zero:8;
}

int main() {
compressed test;
cout<<test.zero<<endl;
test.zero = 500;
cout<<test.zero<<endl;
}```
Keep in mind, no compression is going on right now, the struct is taking 4 bytes, you just can't directly alter any bits after the first 8. For example you can put 10 bits or so on. Or put in 4 variables in the struct each with 8 bits, it'll take only 4 bytes even though one int takes 4 bytes and there's 4. It's realizing that each is only needing 8 bits so it's only allocating one of the ints, but storing all 4 in that one.

6. Yeah I understand that, I read your super long paragraph :P and it made sense the first time.. but yeah its still not compiling.. in fact its went into super-p........ed-off mode.

Code:
```#include <iostream>
using namespace std;

struct compressed {
usigned int zero:8;
usigned int one:8;
usigned int two:8;
usigned int three:8;
}

int main() {
compressed test;
cout << test.zero << endl;
test.zero = 500;
cout << test.zero << endl;

cin.get();
}```
is equal to:

5 C:\Projects\dfdsfsdf.cpp syntax error before `int'
6 C:\Projects\dfdsfsdf.cpp syntax error before `int'
7 C:\Projects\dfdsfsdf.cpp syntax error before `int'
8 C:\Projects\dfdsfsdf.cpp syntax error before `int'
11 C:\Projects\dfdsfsdf.cpp semicolon missing after declaration of ` compressed'
11 C:\Projects\dfdsfsdf.cpp ISO C++ forbids defining types within return type
11 C:\Projects\dfdsfsdf.cpp extraneous `int' ignored
11 C:\Projects\dfdsfsdf.cpp `main' must return `int'
11 C:\Projects\dfdsfsdf.cpp semicolon missing after declaration of ` struct compressed'
C:\Projects\dfdsfsdf.cpp In function `int main()':
13 C:\Projects\dfdsfsdf.cpp 'struct compressed' has no member named ' zero'
14 C:\Projects\dfdsfsdf.cpp 'struct compressed' has no member named ' zero'
15 C:\Projects\dfdsfsdf.cpp 'struct compressed' has no member named ' zero'
ROFL, awesome, no?

7. It works you just forgot a semicolon after your struct and you spelled unsigned wrong...no worries.

Code:
```#include <iostream>
using namespace std;

struct compressed {
unsigned int zero:8;
unsigned int one:8;
unsigned int two:8;
unsigned int three:8;
};

int main() {
compressed test;
cout << test.zero << endl;
test.zero = 500;
cout << test.zero << endl;

cin.get();
}```

8. Originally Posted by Dae
I'm not sure I see the point of seperating a struct into 4 ints that only store 1 byte each, therefor the struct is the size of an int.. but maybe thats because I decided to wait before I get into the bitshifting tutorial. Theres probably some bitwise operation that you can use that makes it uber efficient
well it can be used for encryption like from the blowfish algorithm, where they work with each block of 8 bits differently, or as Ganoosh was talking about, compression.

9. It works you just forgot a semicolon after your struct and you spelled unsigned wrong...no worries.
Yeah, I just typed it u[ quickly in the quick reply while I was tired, so I made a good amount of mistakes.
Sorry about that Dae, I made it more aggrivating than it was just cuz of those syntax errors.

10. Originally Posted by Dae
Calling all guru's! Answer thy plee! (this threads question, wth is : for)

I'd test by doing a simple:
unsigned int zero:8;

Then set it to say 5000, and bitshift it (and cout after each shift) to test the effects.. if I could even compile it:
':' is only for struct declaration.

You may think that
Code:
```struct{
char a:4;
char a:4;
}```
leads to a single byte size struct. You're wrong. The compiler chooses the size of the struct and that one probably will be 2 bytes big. And you can't thell in that case if your 4 bits will be the first 4 bits of the second.... 0000111100001111 (will the 4 bits be 0000 or 1111 ?? ). To solve this problem refer to the pragma pack precompiler directive.
http://msdn.microsoft.com/library/de...m/pragm_22.asp

I already add a similar problem, and with it I learned a lot

11. sorry your post (xErath) confused me, i thought we got it right, we know that the union keeps the same size and the struct is infact the size of an unsigned int but the 32 bits are split up into blocks of 8. That second link you gave didnt really help, because theres no explanation. Plus your example you have two char's named a so that wouldnt work but if you had a and had b be the second one, than a would get the first 4 bits then b would get the next 4.

12. xErath, I see what you're getting at, but we are right. It does compress the space, however it's working beacause they are all of the same type and are all 8 bits. For example, if you mix types and sizes of the bitfields, it won't work properly. The way it works is that since there are 4 ints, and each is only taking a byte, it easily allocates only 4 bytes and stores the 4 ints in those 4 bytes. However, if you were to add another int in there
unsigned int negone:8;
even with 8 bits, the struct will become 8 bytes. Because you can't allocate an int of only one byte. So rather, bitfields are source code, but are manipulated as possible when compiled. Adding other types would also change size. So here's what I'm saying. It only compresses when it follows the standard rules of regular computer science and type sizes. So saying:
Code:
```union {
int one;
int two;
}```
Would only take 4 bytes, because it allocates only one variable at a time, and any others would point to it. For example if you set one a value, but not two, the value in two would be of one, and if you set the value of two afterwards, the value in one would be erased. But that's a union, it works like that, a struct with 2 ints would normally take 8 bytes.
So saying:
Code:
```struct {
int one:16;
int two:16;
};```
Would also take only 4 bytes, because before compiliation it realizes there's 2 ints that only need 16 bits. But it can't allocate half an int (2 bytes), so it allocates a whole int, but stores both ints in the one in their own 16 bit fields(hence why it's called a bit field). For example, a stored int:
10101010111010011100110010010110 << a stored 32 bit int (would be how it's stored)
1010101011101001 1100110010010110 << but would be represented like this
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
number one: 16 bits | number two: 16 bits
However, it only does that because it can, and doesn't break any rules of allocating memory or the size of certain types. Like I showed in my example with bit operators. But if you had only one unsigned int:16; in the struct, it still has to allocate a whole int, but will only allow modification of 16 sequential(I think?) bits. Like this:
0000000000000000 0000000000000000 << the int
^^^^^^^^^^^^^ << Only these 16 bits can be modified

13. I was talking about the ':' in structs.. The 'a' stuff was a typo. should be a and b. Whenever you declare a struct for wich the size is critical, first make sure of its size with sizeof operator. also ':' doesn't compress space what so ever. It reduces the amount of space a variable has available. In your case each int will fit only in 8 bits. Be carefull later when manipulating those vars.

now a small quiz
Code:
```#include <iostream>
typedef struct{
int a:1;
int b:1;
int c:1;
int d:1;
int e:1;
int f:1;
int g:1;
} A;

#pragma pack(1)

typedef struct{
int a:1;
int b:1;
int c:1;
int d:1;
int e:1;
int f:1;
int g:1;
} B;

int main(){
std::cout<<"sizeof A "<<sizeof(A)<<std::endl;
std::cout<<"sizeof B "<<sizeof(B)<<std::endl;
return 0;
}```
which is the output of that code ??

in gcc it is
Code:
```sizeof A 4
sizeof B 1```
in VC++ 6 it is
Code:
```sizeof A 4
sizeof B 4```

14. You're missing what I'm saying, the example you gave won't compress because the struct still follows the rules that an int is 4 bytes. So if you can't evenly make the number of int and their bitfields equal up to a certain number of int size, it won't compress.
Here's an example program.
Code:
```#include <iostream>
using namespace std;

typedef struct {
int one;
int two;
int three;
int four;
} normal;

typedef struct {
int one:8;
int two:8;
int three:8;
int four:8;
} compressed;

typedef struct {
int one:8;
int two:8;
int three:8;
} partcomp;

typedef struct {
int one:8;
int two:8;
int three:8;
int four:8;
int five:8;
} uncomp;

int main() {
cout<<"sizeof normal: "<<sizeof(normal)<<endl; // 16 bytes, 4 for each int, 4 ints
cout<<"sizeof compressed: "<<sizeof(compressed)<<endl; // 4 bytes, byte for each int, 4 ints
/* each of the 4 ints can fit into the size of 1, so only allocate one int and fit all 4
numbers into the one*/
cout<<"sizeof partially compressed: "<<sizeof(partcomp)<<endl; // 4 bytes, it fits all 3 ints into the
/* one int, however you can't allocate a 3 byte int, so an extra byte is put in there. Still
a kinda of compression*/
cout<<"sizeof uncompressed: "<<sizeof(uncomp)<<endl; // 8 bytes, it is able to allocate one
/* int and hold the first four numbers, but you can't change the size of an int, so it adds
another int to hold the fifth int, but even though it only needs 8 bits, but as shown, it
still needs to allocate a whole int*/
cin.get();
}```
Int GCC this output is:
sizeof normal: 16
sizeof compressed: 4
sizeof partially compressed: 4
sizeof uncompressed: 8
Try it, you'll see what I mean. You're example
Code:
```typedef struct{
int a:1;
int b:1;
int c:1;
int d:1;
int e:1;
int f:1;
int g:1;
int h:1;
} A;```
Does not compress, because that's allocating 8 1 bit ints, which will fit in one byte, so it will
compress it into one int, however, it still needs to allocate the whole int (32 bits, 4 bytes of memory), so that will come out to 4 bytes.
The bitfield operators themselves aren't what's doing the compression, it's the struct. Remember it follows basic rules, so even if it can fit all the numbers into one byte and only allocates one int, it has to allocate 4 bytes cuz it's an int. So the number of variables, bitfield size and variable type have to be in relation and fit evenly.
Apparently the pragma pack does not follow those basic rules and will only allocate one byte to fit all those number instead of allocating the whole normal int.

15. Originally Posted by JoshR
It works you just forgot a semicolon after your struct and you spelled unsigned wrong...no worries.

Code:
```#include <iostream>
using namespace std;

struct compressed {
unsigned int zero:8;
unsigned int one:8;
unsigned int two:8;
unsigned int three:8;
};

int main() {
compressed test;
cout << test.zero << endl;
test.zero = 500;
cout << test.zero << endl;

cin.get();
}```
LOL, thanks! I must have officially went blind last night.

Oh I see JoshR, encrypting that would make sense as a use for this, however I agree with Erath on the fact that it isnt giving any compression. The reason is because if you used a char instead of int:8, then it would be the same amount of bits, hence the entire point of going int:8 is lost (however if you used methods thats on that bitwise manipulation tutorial page couldnt it?).

And no, Erath, I dont think:

Code:
```struct{
char a:4;
char a:4;
}```
Would work, because you cant allocate less than a byte (8 bits).. I dont think, can you? meh, I'll read these next posts now.

Popular pages Recent additions