Like Tree2Likes
  • 1 Post By Neo1
  • 1 Post By CornedBee

proper way to define a variable type

This is a discussion on proper way to define a variable type within the C++ Programming forums, part of the General Programming Boards category; I just compiled some code I've been working on at a different OS/compiler and realised that Code: sizeof(unsigned long) returns ...

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    62

    proper way to define a variable type

    I just compiled some code I've been working on at a different OS/compiler and realised that
    Code:
    sizeof(unsigned long)
    returns 4 in one pc and 8 in another.

    I've heard that bytesize conventions for basic variables were not particularly "universal" before but this is the 1st time I've had a problem with it.

    how do I make a typedef that clearly indicates to whatever compiler compiler I want u32 to be an 32bits unsigned and u64 to be 64bits?

  2. #2
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by killme View Post
    I just compiled some code I've been working on at a different OS/compiler and realised that
    Code:
    sizeof(unsigned long)
    returns 4 in one pc and 8 in another.

    I've heard that bytesize conventions for basic variables were not particularly "universal" before but this is the 1st time I've had a problem with it.

    how do I make a typedef that clearly indicates to whatever compiler compiler I want u32 to be an 32bits unsigned and u64 to be 64bits?
    Just use the ones defined in cstdint. uint32_t and uint64_t in your case.
    King Mir likes this.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,157
    Quote Originally Posted by Neo1 View Post
    Just use the ones defined in cstdint. uint32_t and uint64_t in your case.
    That assumes a C++11 implementation.

    Before that, it was a bit tougher. Various techniques, such as using macros to identify the compiler and, based on that, using typedefs. For example, if an unsigned long type is known to be 32 bits .....
    Right 98% of the time, and don't care about the other 3%.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    2,266
    on intel/amd architectures, you can generally assume that sizeof(long) == sizeof(void*), so if the size of a pointer is determined to be 4, and you need a data type that is 8 bytes wide, then you know that you need to use long long, or whatever 64-bit integer type your compiler provides.

    remember that this assumption may not hold true on other architectures, and should generally not be considered portable. as I understand the standard (3.9.2.3), it does not specify how much storage a pointer occupies.
    Code:
    namespace life
    {
        const bool change = true;
    }

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,639
    Quote Originally Posted by grumpy View Post
    That assumes a C++11 implementation.

    Before that, it was a bit tougher. Various techniques, such as using macros to identify the compiler and, based on that, using typedefs. For example, if an unsigned long type is known to be 32 bits .....
    Back in the day I just used templates to work it out:

    Code:
    #include <limits>
    namespace detail
    {
        enum
        {
            bits_per_byte = std::numeric_limits< unsigned char >::digits
        };
        template < typename Integer >
        struct Traits
        {
            typedef Integer
                type;
            enum 
            {
                bits = bits_per_byte * sizeof( type ) 
            };        
        };
        template < >
        struct Traits< void >
        {
            typedef void
                type;
            enum 
            {
                bits = 0 
            };    
        };    
        template < bool Condition, typename Then, typename Else >
        struct If : Traits< Then >
        {    };
        template < typename Then, typename Else >
        struct If < false, Then, Else > : Traits< Else >
        {    };
    }
    namespace lower_bound 
    {
        template < std::size_t Bits >
        struct unsigned_bits : detail::Traits
        < 
            typename detail::If
            < 
                Bits <= detail::bits_per_byte, 
                unsigned char, 
                typename detail::If
                < 
                    Bits <= detail::bits_per_byte * sizeof( unsigned short ), 
                    unsigned short, 
                    typename detail::If
                    <
                        Bits <= detail::bits_per_byte * sizeof( unsigned int ), 
                        unsigned int, 
                        typename detail::If
                        <
                            Bits <= detail::bits_per_byte * sizeof( unsigned long ), 
                            unsigned long, 
                            typename detail::If
                            <
                                Bits <= detail::bits_per_byte * sizeof( unsigned long long ), 
                                unsigned long long, 
                                void
                            >::type
                        >::type
                    >::type
                >::type
            >::type 
        >
        {    };
        template < std::size_t Bits >
        struct signed_bits : detail::Traits
        <
            typename detail::If
            < 
                Bits <= detail::bits_per_byte, 
                signed char, 
                typename detail::If
                < 
                    Bits <= detail::bits_per_byte * sizeof( signed short ), 
                    signed short, 
                    typename detail::If
                    <
                        Bits <= detail::bits_per_byte * sizeof( signed int ), 
                        signed int, 
                        typename detail::If
                        <
                            Bits <= detail::bits_per_byte * sizeof( signed long ), 
                            signed long, 
                            typename detail::If
                            <
                                Bits <= detail::bits_per_byte * sizeof( signed long long ), 
                                signed long long, 
                                void
                            >::type
                        >::type
                    >::type
                >::type
            >::type
        >
        {    };
    }
    template < std::size_t Bits >
    struct unsigned_bits : detail::Traits
    <
        typename detail::If
        < 
            lower_bound::unsigned_bits< Bits >::bits == Bits, 
            typename lower_bound::unsigned_bits< Bits >::type, 
            void
        >
        ::type
    >
    {    };
    template < std::size_t Bits >
    struct signed_bits : detail::Traits
    <
        typename detail::If
        < 
            lower_bound::signed_bits< Bits >::bits == Bits, 
            typename lower_bound::signed_bits< Bits >::type, 
            void
        >
        ::type
    >
    {    };
    typedef unsigned_bits< 8 >::type
        uint8;
    typedef signed_bits< 8 >::type
        int8;
    typedef unsigned_bits< 16 >::type
        uint16;
    typedef signed_bits< 16 >::type
        int16;
    typedef unsigned_bits< 32 >::type
        uint32;
    typedef signed_bits< 32 >::type
        int32;
    typedef unsigned_bits< 64 >::type
        uint64;
    typedef signed_bits< 64 >::type
        int64;
    /*
        You may need to update your processor for this one!
    */
    typedef unsigned_bits< 128 >::type
        uint128;
    typedef signed_bits< 128 >::type
        int128;
    Code:
    if( numeric_limits< byte >::digits != bits_per_byte )
        error( "program requires bits_per_byte-bit bytes" );
    24bbs.cpp

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    thanks every1,
    up until now I've been trying to keep the project I'm working on C++98 compatible but, seeing that C++11 is by far the best option here, I might opt for it.
    Now I just have to convince my research partner/boss (I'd say boss if he didn't say partner) that physics Phd's who might want to use our code should be smart enough to go get a C++11 compatible compiler.

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    2,266
    Quote Originally Posted by killme View Post
    ...should be smart enough to go get a C++11 compatible compiler.
    you should never make that assumption. people are generally stupid and resistant to change, regardless of their level of education. if anything, education tends to make them confidently stupid. I'm not saying that any given physics phd is necessarily a stupid person, but my experience has shown me that even people with college degrees very often lack critical thinking and problem solving skills, and any level of intelligence should not be assumed. this is a critical element of software development.

    apart from that, C++11 is the standard now, and its use should be strongly encouraged.
    Code:
    namespace life
    {
        const bool change = true;
    }

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Quote Originally Posted by grumpy View Post
    That assumes a C++11 implementation.

    Before that, it was a bit tougher.
    Code:
    #include <boost/cstdint.hpp>
    
    boost::int32_t i32;
    Doesn't look that tough to me
    Elkvis likes this.
    All the buzzt!
    CornedBee

    "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

  9. #9
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,230
    Quote Originally Posted by Elkvis View Post
    on intel/amd architectures, you can generally assume that sizeof(long) == sizeof(void*)
    Actually, all Microsoft-compatible compilers for Windows have long as 32 bits, even for amd64 architectures.

    On most relevant platforms, sizeof(int) == 4 and sizeof(long long) == 8. That's true across many different compilers.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,639
    Quote Originally Posted by brewbuck View Post
    Actually, all Microsoft-compatible compilers for Windows have long as 32 bits, even for amd64 architectures.

    On most relevant platforms, sizeof(int) == 4 and sizeof(long long) == 8. That's true across many different compilers.
    I don't know if Cygwin (running on a 64-bit Intel chip, Windows 8 computer) counts as "Microsoft-compatible" under your definition, but mine reports sizeof(long) == 8.
    Code:
    if( numeric_limits< byte >::digits != bits_per_byte )
        error( "program requires bits_per_byte-bit bytes" );
    24bbs.cpp

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Quote Originally Posted by Sebastiani View Post
    I don't know if Cygwin (running on a 64-bit Intel chip, Windows 8 computer) counts as "Microsoft-compatible" under your definition, but mine reports sizeof(long) == 8.
    It's not Microsoft-compatible. Cygwin tries to be Linux-compatible.
    All the buzzt!
    CornedBee

    "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

  12. #12
    Registered User
    Join Date
    Oct 2006
    Posts
    2,266
    Quote Originally Posted by brewbuck View Post
    Actually, all Microsoft-compatible compilers for Windows have long as 32 bits, even for amd64 architectures.

    On most relevant platforms, sizeof(int) == 4 and sizeof(long long) == 8. That's true across many different compilers.
    I could be pedantic and say that I was technically correct because I used the word "generally" instead of "always," and windows is but one exception among a great many intel/amd-based platforms, of which windows is the only one that I've seen that uses a 32-bit long in 64-bit mode. This link has a pretty comprehensive list, although I'm not entirely certain if all the platforms listed are intel/amd-based.

    instead, I'll just concede the point because windows is so much more common than all the other platforms (combined?) that run on that architecture.
    Code:
    namespace life
    {
        const bool change = true;
    }

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,157
    Quote Originally Posted by CornedBee View Post
    Code:
    #include <boost/cstdint.hpp>
    
    boost::int32_t i32;
    Doesn't look that tough to me
    ..... except that not everyone uses boost. Whether they should or not is a topic for discussion another day.
    Right 98% of the time, and don't care about the other 3%.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Is it possible to set type for define macro?
    By 6tr6tr in forum C++ Programming
    Replies: 5
    Last Post: 04-16-2008, 01:32 PM
  2. how to define a range of type in C++ or C?
    By zaracattle in forum C++ Programming
    Replies: 24
    Last Post: 03-23-2007, 03:31 PM
  3. How to define a variant record type in C
    By Diepvien_007 in forum C Programming
    Replies: 2
    Last Post: 03-12-2003, 03:23 PM
  4. define a boolean type
    By Krem in forum C Programming
    Replies: 6
    Last Post: 10-04-2002, 11:54 AM
  5. variable type char to variable type int
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 07-15-2002, 08:52 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21