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

  1. #16
    myNegReal
    Join Date
    Jun 2005
    Posts
    100
    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. #17
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    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.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  3. #18
    myNegReal
    Join Date
    Jun 2005
    Posts
    100
    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. #19
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    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;
    }
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  5. #20
    myNegReal
    Join Date
    Jun 2005
    Posts
    100
    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. #21
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    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?
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  7. #22
    *this
    Join Date
    Mar 2005
    Posts
    498
    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. #23
    *this
    Join Date
    Mar 2005
    Posts
    498
    Quote 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. #24
    myNegReal
    Join Date
    Jun 2005
    Posts
    100
    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. #25
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    Quote 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
    http://cboard.cprogramming.com/showthread.php?t=54080

  11. #26
    *this
    Join Date
    Mar 2005
    Posts
    498
    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. #27
    myNegReal
    Join Date
    Jun 2005
    Posts
    100
    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
    Last edited by Ganoosh; 06-22-2005 at 02:56 PM.

  13. #28
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    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
    Last edited by xErath; 06-22-2005 at 03:25 PM.

  14. #29
    myNegReal
    Join Date
    Jun 2005
    Posts
    100
    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. #30
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote 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.
    Last edited by Dae; 06-22-2005 at 03:59 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Writing Code
    By ILoveVectors in forum C++ Programming
    Replies: 4
    Last Post: 06-13-2005, 12:27 AM
  2. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  3. Seems like correct code, but results are not right...
    By OmniMirror in forum C Programming
    Replies: 4
    Last Post: 02-13-2003, 01:33 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 4
    Last Post: 01-16-2002, 12:04 AM