Skip to main content
gamedev.net
🔒 Locked

__int32 in linux

Started by Wavesonics Dec 28, 2006 at 4:51 PM 10 replies 12.3k views
Original Post
Wavesonics
Wavesonics
I have a project I have worked on which has been designed to be cross platform but has only been compiled in windows so far. Now i finally have a linux box to compile on so I'm trying to get it going. But where as I had no compile errors on g++ under windows I am getting errors with my __int32,__int16 etc in g++ on my linux box. Anyone heard of things like this? I have tried including stddef.h, and cstddef and neither seem to fix the problem. Any ideas? On linux I'm sure I'm using gcc4.1, not sure what it was on windows.
jflanglois
jflanglois
Well, first of all, is the size of your variables that important?

If it is, then I suggest you check out Boost.Integer's cstdint.hpp. Even then, though, it will not be completely platform independent (short of the C++ standard defining explicitly sized types).


jfl.
Anon Mike
Anon Mike
__int32 and kin are not standard types, they're Microsoft'isms.

The quick fix is to typedef the proper sized type for your platform.
-Mike
Zahlman
Zahlman
Quote:
Original post by jflanglois
Well, first of all, is the size of your variables that important?

If it is, then I suggest you check out Boost.Integer's cstdint.hpp. Even then, though, it will not be completely platform independent (short of the C++ standard defining explicitly sized types).


jfl.


Shouldn't it be possible to do some template metaprogramming magic (I'm thinking SFINAE and class member "templated typedef"s) to match up the native types to requested sizes? (Of course, in cases where none of char, short, int or long is the desired size under the current ABI, some kind of class wrapper would have to be substituted... I've actually been working on said class wrapper, but not with particularly good focus x.x)

Wavesonics
Wavesonics
Yes the size is very important. I'm reading in specific parts of binary files which must be of exact sizes.

It strikes me as odd that I was only using cstd libs and headers and that I was some how using a windows only #define...

Any ways the last comment worked, thanks a million guys!
Nitage
Nitage
The __intXX types are built-in to the micorsoft compiler, so you don't need to #include anything extra for them.

If you're trying to create portable code in VC++ 2003/2005 it might help you to disable the microsoft language extensions. They're under the C++/Language tab in the project option dialog (and the option can be set per translation unit if you need to include windows specific headers).
jflanglois
jflanglois
Quote:
Original post by Zahlman
Shouldn't it be possible to do some template metaprogramming magic (I'm thinking SFINAE and class member "templated typedef"s) to match up the native types to requested sizes? (Of course, in cases where none of char, short, int or long is the desired size under the current ABI, some kind of class wrapper would have to be substituted... I've actually been working on said class wrapper, but not with particularly good focus x.x)


You're exactly right (but you knew that already, right? ;))

I did it as an exercise:

template< bool B, class Then = void, class Else = void >struct enable_ifelse_c {    typedef Then type;};template< class Then, class Else >struct enable_ifelse_c< false, Then, Else > {    typedef Else type;};template< unsigned Size >struct unsigned_sized_integral {    typedef typename enable_ifelse_c< sizeof( char unsigned ) == Size, char unsigned,         typename enable_ifelse_c< sizeof( short unsigned ) == Size, short unsigned,            typename enable_ifelse_c< sizeof( int unsigned ) == Size, int unsigned,                typename enable_ifelse_c< sizeof( long unsigned ) == Size, long unsigned,                    typename enable_ifelse_c< sizeof( long long unsigned ) == Size, long long unsigned,                        void                    >::type                >::type            >::type        >::type    >::type type;};typedef unsigned_sized_integral< 1 >::type uint8_t;typedef unsigned_sized_integral< 2 >::type uint16_t;typedef unsigned_sized_integral< 4 >::type uint32_t;typedef unsigned_sized_integral< 8 >::type uint64_t;template< unsigned Size >struct signed_sized_integral {    typedef typename enable_ifelse_c< sizeof( char signed ) == Size, char signed,         typename enable_ifelse_c< sizeof( short signed ) == Size, short signed,            typename enable_ifelse_c< sizeof( int signed ) == Size, int signed,                typename enable_ifelse_c< sizeof( long signed ) == Size, long signed,                    typename enable_ifelse_c< sizeof( long long signed ) == Size, long long signed,                        void                    >::type                >::type            >::type        >::type    >::type type;};typedef signed_sized_integral< 1 >::type int8_t;typedef signed_sized_integral< 2 >::type int16_t;typedef signed_sized_integral< 4 >::type int32_t;typedef signed_sized_integral< 8 >::type int64_t;


It's gawdaful in terms of formatting, and there are a couple of issues:

- I'm not sure if long long will have issues with certain compilers. [update] The latest version of GCC that I have access to right now is 3.2.3, which does not like long long
- I'm pretty sure that a char will be 8 bits by definition, but not quite; so should the size be in bits or chars (i.e. in the first version I multiplied the sizeof by 8)? What is a 13-bit integral type?

Anyway, thanks for the nudge, Zahlman.


[edit] As for the class wrapper you mentioned, I should think it would be put in place of void in my code. Or were you thinking of a different way of doing this?


jfl.

[Edited by - jflanglois on December 29, 2006 6:47:02 PM]
jflanglois
jflanglois
Quote:
Original post by Anonymous Poster
I do like that, but there are some problems with it as you say, in addition to those none of the types may map to a 16 bit int as neither short, long or int are of defined sizes and may all be the same size.
Personally I use http://www.gamedev.net/community/forums/viewreply.asp?ID=2771066 which I think is guaranteed to work, due to stdint being C99, but it would be nice if ms used it.


No one said it would be guaranteed to work for a specific size. If a specific size does not map to a fundamental integral type, then (un)signed_sized_integral yields void. This is where a class wrapper would come in, as Zahlman mentioned.

As for stdint.h, that was my first suggestion. Boost.Integer includes an implementation of C99's stdint.h (boost/cstdint.hpp).


jfl.
Zahlman
Zahlman
My idea actually was more or less the other way around: make a generic class wrapper (templated on bit count), and then specialize that (using SFINAE tricks) for the types that can be supported directly. Something like

template <size_t bits>class Integer {  // calculate at compile time a necessary amount of storage, and have a char[]  // buffer as a data member, possibly doing some alignment magic too. Implement  // all the appropriate operators.};template <size_t bits>class integer_traits {  typedef Integer<bits> type;};template <>class integer_traits<CHAR_BITS>  typedef char type;};// use SFINAE to create other specializations of integer_traits where possible

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.