Thread: proper way to define a variable type

  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.
    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,815
    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%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    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.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    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:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  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
    3,445
    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.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    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
    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
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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,708
    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:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    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
    3,445
    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.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    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%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

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, 04: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