Thread: controlling how many bytes a variable takes up

  1. #1
    Registered User
    Join Date
    Jul 2007

    controlling how many bytes a variable takes up

    Is there any way to specifically create a 2, 4, (or some other arbitrary number) byte integer instead of using a short int or long int and hoping it will take up the correct number of bytes?

    The reason I ask is that I am working on a game, in which the board will be made up of tiles. These tiles will each have a specific type to keep track of whether that certain tile is a grass tile, a water tile, etc. I'll probably have more than 255 different types of tiles so I can't get away with using an unsigned char. On a small board of 1000 * 1000, the difference between using two bytes to store each type and using four bytes to store each type is 2 MB of wasted space (which would happen if my compiler decided to use four bytes for a short int). Although not a huge problem, still not great.

    Most of the time it doesn't matter if a short int takes up 2 or 4 bytes. The exception is when you allocate large (multidimensional) arrays of them.

    "uint8", "uint16", "uint32", & "uint64" come to mind (I can't remember where I saw them though), but my compiler complains that they aren't declared when I try to use them.

    I suppose one way might be to create a class that internally handles unsigned char arrays and overload it's operators, but I was hoping there would be a better solution.

  2. #2
    Registered User
    Join Date
    Oct 2001
    you could use bitfields:
    class A
        unsigned uint:5; //uint is 5 bits long
        int sint:6; //sint is 6 bits long
    I don't know how this would work with passing to functions and all though.
    Last edited by robwhit; 07-29-2007 at 04:40 PM.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Portland, OR
    Quote Originally Posted by mike_532532 View Post
    Is there any way to specifically create a 2, 4, (or some other arbitrary number) byte integer instead of using a short int or long int and hoping it will take up the correct number of bytes?
    Look at the C99 standard header stdint.h for definitions of specific size integer types. If you can't use that header file, the best approach is to just create a platform-dependent "types.h" file which defines the types for each compiler you will be compiling under.

    If you're only worrying about YOUR compiler, then just figure out which type is the right size and use it. The compiler isn't going to suddenly change it.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Farncombe, Surrey, England
    Since the size of (for example) short and long integers aren't strictly defined, the correct way to "know" the size of any variable is to have a definition that matches the compiler, e.g. have a include-file called "types.h" (or something like that).

    This file should then contain defitions like:
    typedef unsigned char  uint8;
    typedef unsigned short uint16;
    #if __64BIT__
    typedef unsigned int uint32;
    typedef unsigned long uint64;
    typedef unsigned long uint32;
    typedef unsigned __int64 uint64;
    Of course, you should probaboy also define your own "tilenotype", such as:
    #define uint16 tilenotype;
    That way, you can quite easily change the type to a different type if you need to.

    Bitfields are useful sometimes, but using "odd-sized" bitfields [not 8, 16, 32 or 64 wide] will increase the code-size, because the compiler will have to mask the bits.

    Also watch out for alignment issues - if, in a struct, you put a 16-bit next to a 32-bit value, it's most likely going to use up 4 bytes in the struct, even though only 2 is used to store soemthing.

    Note that you may need to change your "types.h" if you use a different compiler.

    Note also the "__64BIT__" isn't a standard thing - but there's usually a way to detect 32 vs 64-bit compile, so you need to "replace" this with the appropriate define (or generate __64BIT__ from the relevant define made by the compiler).


  5. #5
    Registered User
    Join Date
    Jul 2007
    From your reply matsp, can I infer that the "uint8/16/32" I refered to earlier is something that the programmer defines and isn't defined by the implementation?

    I thought C defined (u/s)int(8/16/32) and then each platform's implementation simply typedefed all of the regularly used int's (based on things like processor size and whatever works best for that platform).

    /* type.h */
    #ifndef __TYPE_H
    #define __TYPE_H
    typedef sint32 int;
    typedef sint32 long int;
    typedef uint32 unsigned long int;
    typedef sint8 char;
    Am I wrong about that?

    matsp, what you suggested will be the perfect solution. Thanks.

  6. #6
    Registered User
    Join Date
    Jan 2005
    C++ doesn't have the stuff in C99's stdint.h yet, so it just depends on your compiler as to whether it supports those for C++ or not. If it doesn't, then you have to make your own header and typedefs, otherwise use those.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Boost has cstdint.hpp, which defines all those C99 types pretty much on all compilers.
    All the buzzt!

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  2. Question about printing a variable???
    By Hoser83 in forum C++ Programming
    Replies: 2
    Last Post: 03-31-2006, 01:57 PM
  3. static class variable vs. global variable
    By nadamson6 in forum C++ Programming
    Replies: 18
    Last Post: 09-30-2005, 03:31 PM
  4. Problem with a char variable set as a letter
    By 7smurfs in forum C++ Programming
    Replies: 6
    Last Post: 12-10-2004, 01:25 PM
  5. Use of variable
    By alice in forum C Programming
    Replies: 8
    Last Post: 06-05-2004, 07:32 AM