forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

why are u32/uint32_t/SceUInt32 defined as longs?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
snowsquirrel



Joined: 24 Feb 2008
Posts: 51

PostPosted: Fri Jun 06, 2008 12:36 pm    Post subject: why are u32/uint32_t/SceUInt32 defined as longs? Reply with quote

Why is u32 defined as an unsigned long int? I know on my 32 bit systems, a long and int are both 32. So it doesn't matter, which is used.... kind of... one really annoying side effect are the compiler warnings generated from printf.
Code:

u32 mynum  = 25L;
printf( "my num %u\n", mynum );

This generates a warning because it wants you to use %ul instead of %u.

I looked at stdint.h on a 32bit and 64bit system and both just used an unsigned int, not an unsigned long.

It bugs me, as I maintain both a PC, and PSP version of my project.

Just wondering if there is a valid reason, or if it is just arbitrary?

~S
Back to top
View user's profile Send private message
pspZorba



Joined: 22 Sep 2007
Posts: 156
Location: NY

PostPosted: Fri Jun 06, 2008 1:15 pm    Post subject: Reply with quote

If I remember well:

a short is always 16bits
a long is always 32bits

and depending on the platform an int is either a short or a long

so if you want to be platform independent u32 has to be an unsigned long
not an unsigned int.
_________________
--pspZorba--
NO to K1.5 !
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Fri Jun 06, 2008 4:03 pm    Post subject: Reply with quote

Uh... no.

A short is 2 bytes.
An int is 2 or 4 bytes, depending on the CPU (always 4 on 32 bit or better CPUs). To be technical, a short int is 2 bytes, while a long int is 4 bytes. "int" is just shorthand for "long int" on most compilers. Note that a "long int" is NOT the same thing as a "long".
A long is 4 or 8 bytes, depending on the CPU.
A long long is 8 bytes.
A pointer is 4 or 8 bytes, depending on the CPU.
Back to top
View user's profile Send private message AIM Address
bulb



Joined: 19 Jan 2006
Posts: 50

PostPosted: Fri Jun 06, 2008 11:00 pm    Post subject: Reply with quote

Actually, neither is correct. The size of types in C/C++ are not fixed - the implementation is free to choose whatever size it wants. Hence the use of sizeof. This is what Java and C# "fixed". :)

I once worked with a Z80 compiler that had short defined as 1 byte (8 bits) long, and on one esoteric architecture a short was defined as 12 bits (yes, not all systems use multiples of 8 and not all systems use von Neumann architecture).

As to original poster, I think this was just arbitrary (preference of style). I also like to use long (instead of int) when I want to define 32-bit. You could switch to C++ streams and live without those warnings, because C++ Standard Library is typesafe.
Back to top
View user's profile Send private message
snowsquirrel



Joined: 24 Feb 2008
Posts: 51

PostPosted: Fri Jun 06, 2008 11:16 pm    Post subject: Reply with quote

Getting o/t here, but I find streams a PITA to use, plus they tend to blow up mem usage on embedded systems.

Printf is probably the only old school technique I continue to employ. I wish they would make modernized version of of it, something like C# version of formatted strings where the format operators are not type specific. Of course that is easy in C# where everything has a toString() method.

~S
Back to top
View user's profile Send private message
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Sat Jun 07, 2008 12:06 am    Post subject: Reply with quote

http://en.wikipedia.org/wiki/C_variable_types_and_declarations

Quote:
There is some confusion in novice C programmers as to how big these types are. The standard is specifically vague in this area:

* A short int must not be larger than an int.
* An int must not be larger than a long int.
* A short int must be at least 16 bits long.
* An int must be at least 16 bits long.
* A long int must be at least 32 bits long.
* A long long int must be at least 64 bits long.

It may be vague and seem arbitrary, but in C that's a feature and we like it that way!
Back to top
View user's profile Send private message Visit poster's website
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat Jun 07, 2008 2:48 am    Post subject: Reply with quote

Very true. I just described the majority of 16 / 32 / 64 bit compilers. It's rare that you'll run into anything else, so my post is the most relevant to folks here.
:)
Back to top
View user's profile Send private message AIM Address
whistler



Joined: 04 Mar 2008
Posts: 40

PostPosted: Sat Jun 07, 2008 4:57 am    Post subject: Reply with quote

J.F. wrote:
Note that a "long int" is NOT the same thing as a "long".

sure it is:) when you use the long modifier on its own the int is implied
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat Jun 07, 2008 7:12 am    Post subject: Reply with quote

whistler wrote:
J.F. wrote:
Note that a "long int" is NOT the same thing as a "long".

sure it is:) when you use the long modifier on its own the int is implied


Depends on the compiler. There's that "vagueness" that Oopo mentioned. :) The compilers I grew up on, long and long int were two separate types.

I guess seeing what we use here, we should probably stick to whatever gcc uses for the types.
Back to top
View user's profile Send private message AIM Address
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Sat Jun 07, 2008 10:38 am    Post subject: Reply with quote

When it comes to C, if it isn't defined specifically in the standard then you should be very careful. That's what we call 'undefined behavior' and there's no reason to count on it being the same on every system, or even on every execution.

Usually I create a types.h file, with defines for things like uint08 and sint32. That way I can change them in one place in the code for whatever platform and compiler I end up using at any given time.
Back to top
View user's profile Send private message Visit poster's website
TyRaNiD



Joined: 18 Jan 2004
Posts: 918

PostPosted: Sat Jun 07, 2008 5:10 pm    Post subject: Reply with quote

Tbh I find that GCC's printf warnings to be somewhat overzelous, they made changes between 4.0 and 4.1 which added more petty warnings, one of them being things like the long int shit. Psplink compiled fine on 4.0.2 with all warnings, on 4.1 it spat out a fair number of format warnings. Annoys me to the extent that I tend to just turn them off, I am only really interested in ones which indicate missing parameters or mismatches %s to pointers. Anything else is generally a display issue/portability issue vs. rather than a potential crash.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sat Jun 07, 2008 7:42 pm    Post subject: Reply with quote

ooPo wrote:
Usually I create a types.h file, with defines for things like uint08 and sint32. That way I can change them in one place in the code for whatever platform and compiler I end up using at any given time.


I see you insert a 0 to uint8, so I guess you like to have types of same length as possible. :)
Back to top
View user's profile Send private message
Heimdall



Joined: 10 Nov 2005
Posts: 259
Location: Netherlands

PostPosted: Sat Jun 07, 2008 11:43 pm    Post subject: Reply with quote

Yesterday i picked up the "The C programming language" book from K&R and it states that a int is of the same of the platform default (and atleast 16bits) and a short int (or just short) is atmost 16 bits, and a long int (or just long) is at least always 32 bits. So the newlib definition of uint32_t and int32_t are correct by defining it as a long, however if you want to be picky :) you can hack your newlib includes to your favour. I've tested rebuilding the full compiler + sdk with the -Werror flag on and there are my only changes to make int32_t and uint32_t aliased to int and not long:

stdint.h

on line 37 i replaced the original preprocessor code with:
Code:
/* Check if "long" is 64bit */
#if __STDINT_EXP(LONG_MAX) > 0x7fffffff
#define __have_long64 1
#endif


This removed the automatic __have_long32 definition to be defined thus later on int32_t will be mapped to int and not long

then on my SDK i configured it with:

CFLAGS=-Werror ./configure --with-pspdev=/c/pspsdk

and had only to fix the prof.c file because it warns about a missing and a wrong prototypes, so i replaced line 81 of prof.c with:

Code:
void gprof_cleanup(void);
void __mcount(unsigned int, unsigned int);


and now the SDK builds without warning and errors and int32_t are int. I think that if you want to hack your current setup just edit the stdint.h on your psp/include dir like above and it works, BUT!!! from now on you may have broken the portability of your code...
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Sun Jun 08, 2008 2:01 am    Post subject: Reply with quote

hlide wrote:
I see you insert a 0 to uint8, so I guess you like to have types of same length as possible. :)

It pleases my eye when I see things line up nicely. :)
Back to top
View user's profile Send private message Visit poster's website
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sun Jun 08, 2008 2:18 am    Post subject: Reply with quote

Heimdall wrote:
Yesterday i picked up the "The C programming language" book from K&R and it states that a int is of the same of the platform default (and atleast 16bits) and a short int (or just short) is atmost 16 bits, and a long int (or just long) is at least always 32 bits. So the newlib definition of uint32_t and int32_t are correct by defining it as a long,


Only on 32 bit systems! On 64 bit systems, long (or long int) is 64 bits.

Quote:
however if you want to be picky :) you can hack your newlib includes to your favour. I've tested rebuilding the full compiler + sdk with the -Werror flag on and there are my only changes to make int32_t and uint32_t aliased to int and not long:


Did you misspeak above? First you say it's correct to define uint32_t as a long, and now you say you made sure it's aliased to int and NOT long.

I think we need to be clear - on current 32 bit systems, int and long are 32 bits, but on all 64 bit systems, int is 32 and long is 64. So it is NOT correct to alias int32_t/uint32_t to long int as that will fail on all 64 bit systems.

All current gcc versions (the only compiler we care about) alias 32 bit values to int and 64 bit values to long.

Now if you're talking about psp-gcc, you COULD alias int32_t to long since it's compiling for a 32 bit CPU, but the code won't be portable.
Back to top
View user's profile Send private message AIM Address
Heimdall



Joined: 10 Nov 2005
Posts: 259
Location: Netherlands

PostPosted: Sun Jun 08, 2008 7:59 am    Post subject: Reply with quote

i know its not clean, its a hack. but since the psp is 32bits it wouldn't arm to alias int32_t to int. again this is a hack that reduces lots of compiling warnings
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
snowsquirrel



Joined: 24 Feb 2008
Posts: 51

PostPosted: Sun Jun 08, 2008 8:00 am    Post subject: Reply with quote

J.F. wrote:

Now if you're talking about psp-gcc, you COULD alias int32_t to long since it's compiling for a 32 bit CPU, but the code won't be portable.


Which was my original point. on 90% (pulled that number out of my ass) of the platforms out there typedefing int32 as int works. While typedefing it as long, only works on32 bit systems.

~S
Back to top
View user's profile Send private message
Jim



Joined: 02 Jul 2005
Posts: 487
Location: Sydney

PostPosted: Sun Jun 08, 2008 8:57 pm    Post subject: Reply with quote

Quote:
Code:

u32 mynum  = 25L;
printf( "my num %u\n", mynum );

Nonetheless, the only portable version of this code is
Code:

u32 mynum  = 25L;
printf( "my num %u\n", (unsigned int)mynum );

so that's how you make your code correctly portable. There's no portable guarantee that u32 and unsigned int or unsigned long or unsigned long int are the same.

Jim
_________________
http://www.dbfinteractive.com
Back to top
View user's profile Send private message Visit poster's website
jean



Joined: 05 Jan 2008
Posts: 489

PostPosted: Sun Jun 08, 2008 9:30 pm    Post subject: Reply with quote

Apart from portability argumentations, sometimes even procedural coding needs some modelization :) I think of it this way: if i need a type representing a device and i know that there are <255 devices then i could (quick and dirty) choose a char; OR i could define a "device" type as a char and use it instead. Why? Because so i can define functions accepting "device" and not "char" helping me to point out inaccuracies, or (in c++) letting me redefine some operators just to make life more complex.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group