Sign in to follow this  
sakky

Data type sizes

Recommended Posts

Okay, this is a continue of a different post “WORD & DWORD”. To Polymorphic OOP The compiler I use is VS.NET ,does this explain any thing? And the char is one byte, hence the reason I say byte all the time. I would like to know where you got that info, because it is wrong on my machines and my friends. The int is larger then the long on a 64 bit processor. My whole point on all of this is that the int data type has a variant size depending of the processors’ bus. The char, short, and long always stay the same size. I believe that GCC produces that same size as VS.NET. The char is 1 byte, the shrot is 2 bytes, and the long is 4 bytes. The int however, is 4 bytes on my 32 bit processor, and 8 bytes on the friends’ 64 bit processor. That standard sounds not entirely true full, or you miss understand it. The int can only take values from 0 to 65,535 unsigned, and -32,768 to 32,767 signed. Even if it takes up 4 bytes, it can only hold those values. Don’t believe me, try testing it out! But the long however, can hold 2,147,483,648 to 2,147,483,647 signed, and 0 to 4,294,967,295 unsigned. The screwed up thing is, that the int and the long are the same size on my 32 bit processor. But the int STILL can’t even hold the amount of the long because of that standard or some other reason. Because on my machine, sizeof( int ) = 4. And on my friends machine sizeof( int ) = 8. However, sizeof( long ) = 4 on both of ours machines.

Share this post


Link to post
Share on other sites
Quote:
The int can only take values from 0 to 65,535 unsigned, and -32,768 to 32,767 signed.


What do you mean? On a 32bit system an unsigned int takes upto 4.2 billion, give or take. Or am i misunderstanding you?

Share this post


Link to post
Share on other sites
Not sure which language you're talking about so...

From the ISO C99 Standard:

[6.2.5.8] For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type.

[6.3.1.1.1] ...The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int...

Therefore, it seems to me that long int must always have the same or greater range as the int in C.

------------------------------

Someone already quoted this from the ISO C++ 2003 Standard but for completeness:

[3.9.1.2] There are four signed integer types: “signed char”, “short int”, “int”, and “long int.” In this
list, each type provides at least as much storage as those preceding it in the list.


This plainly says that long int provides at least as much storage space as the int. Presumably the compiler wouldn't limit the value range of a type to less than is available in the storage space. I don't know whether this is explicitly prevented by the standard or not... So for C++, I dunno.

Share this post


Link to post
Share on other sites
It matters to some of us. And these things are standardized, at least to a certain extent. So its not really just magically "different" for no reason at all.

Sorry to quote again but:
[C99 6.2.5.5] ... A ‘‘plain’’ int object has the natural size suggested by the architecture of the execution environment...

One of the things I hate about web programming is the lack of concern about following standards. Fortunately, things have been getting better over the last few years.

I should mention that if the range of an unsigned int is limited to 0-65535 for you, it would be specific to your compiler or execution environment, not because of a strange C or C++ rule.

[Edited by - dcosborn on September 20, 2004 6:00:39 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by sakky
My whole point on all of this is that the int data type has a variant size depending of the processors’ bus. The char, short, and long always stay the same size.

I would like to know where you got this information. I don't think it is right.

Quote:
Original post by sakky
I believe that GCC produces that same size as VS.NET. The char is 1 byte, the shrot is 2 bytes, and the long is 4 bytes.

GCC can compile C/C++ code for several platforms. The sizes of the types are different for different platforms. In addition, there are a couple of versions of GCC for the PS2, and a long is 64 bits in one version, but 32 bits in the other.

Quote:
Original post by sakky
The int can only take values from 0 to 65,535 unsigned, and -32,768 to 32,767 signed. Even if it takes up 4 bytes, it can only hold those values.

You are very very confused.

Share this post


Link to post
Share on other sites
Well what I mean is that a int is the same size on a 32 bit processor in the amount of memory it takes up. On a 64 bit processor the int takes up more memory. This is what I’m getting at.

It seams, from what I’ve recently read, is that a int’s size (in bytes) and range are purely dependant on the CPU and Tools used. But a short or a long are not. They are the same size every where and are much better in my opinion to use because I can always rely on them.

I use Visual C++.NET and I have a Athlon XP 1800. When I compile my program with VC, sizeof( int ) = 4 and sizeof( long) = 4. But, I can’t put 2 or 4 million something in a int, but I can with an long. Even though they take up the same amount of memory.

Hence, the long will always be 4 bytes and be able to hold huge values, where as a int has a variable size and can’t hold values as big as a long. This is my point and I think ints suck and shorts and longs rule!

[edit] What does 'nvm' mean?

Share this post


Link to post
Share on other sites
Quote:
Hence, the long will always be 4 bytes and be able to hold huge values, where as a int has a variable size and can’t hold values as big as a long. This is my point and I think ints suck and shorts and longs rule!


Im sorry. But i dont understand what your talking about! Shurly if a long is 4 bytes in length it can hold a value between 0 and 4.2 billion if unsigned. If an int is the same length it will hold the same. Why would a compiler allocate 4 bytes of emeory and only use 2? (Which is your implication in the top post)

Quote:
What does 'nvm' mean?


Never mind.

Share this post


Link to post
Share on other sites
The long and short are just as volatile as the the int. The short, int, and long must each be equal or larger than the previous. So they're all dependent on one another. If an int grows, it may be necessary that the long grow too. The int should never be larger than the long.

I wonder if alignment could be causing your sizeof(int) to equal 4 when its actually 2 or something?

Does this give you 0 or 65536?

#include <iostream>
int main()
{
unsigned int a = 65535;
std::cout << ++a;
return 0;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by sakky
It seams, from what I’ve recently read, is that a int’s size (in bytes) and range are purely dependant on the CPU and Tools used. But a short or a long are not. They are the same size every where and are much better in my opinion to use because I can always rely on them.

Wrong. short is shorthand for short int. long is shorthand for long int. The size isn't fixed. Only that sizeof(short) <= sizeof(int) and sizeof(long) >= sizeof(int).

Quote:
Original post by sakky
I use Visual C++.NET and I have a Athlon XP 1800. When I compile my program with VC, sizeof( int ) = 4 and sizeof( long) = 4. But, I can’t put 2 or 4 million something in a int, but I can with an long. Even though they take up the same amount of memory.

Wrong. From limits.h:

#define INT_MAX 2147483647 /* maximum (signed) int value */
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */
#define LONG_MAX 2147483647L /* maximum (signed) long value */
#define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */




They're exactly the same.

Quote:
Original post by sakky
Hence, the long will always be 4 bytes and be able to hold huge values, where as a int has a variable size and can’t hold values as big as a long. This is my point and I think ints suck and shorts and longs rule!

As I said above, a long isn't guaranteed to be 4 bytes at all. On a 32-bit platform and compiler, a long can hold the same range as an int.

Quote:
Original post by sakky
[edit] What does 'nvm' mean?

nvm = NeVer Mind I think

EDIT: The results of running your program in the other thread on a 64-bit linux machine with GCC:
[root@Winry root]# ./a.out
A int is 4 in bytes
A long is 8 in bytes


[Edited by - Evil Steve on September 20, 2004 7:07:28 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by sakky
My whole point on all of this is that the int data type has a variant size depending of the processors’ bus. The char, short, and long always stay the same size.


Again, I got all of my info directly from the C++ standard, which I quoted in the previous thread. I don't see why you have such trouble believing this.

Quote:
Original post by sakky
The int can only take values from 0 to 65,535 unsigned, and -32,768 to 32,767 signed.

That is completely compiler dependent. For instance, on a 32 bit machine in the VS .NET 2003 compiler an unsigned int will have a range of 0 to 2^32 - 1(over 4 billion) and an int will have a rang of -2^16 to 2^16-1 (under -2 billion and over 2 billion respectively). The ranges you gave are if an int happened to be 16 bits using a 2s compliment system which is not guaranteed to be true (and usually is NOT true as most people nowadays use 32-bit or 64-bit systems). The exact size and range is not given by the standard, it only has guidelines, just like all of the other fundamental integral types excluding the char types (which must be exactly 1 byte in C++ storage units).

Quote:
Original post by sakky
Even if it takes up 4 bytes, it can only hold those values.

Again, you are mistaken. It's compiler dependent.


Quote:
Original post by sakky
Don’t believe me, try testing it out! But the long however, can hold 2,147,483,648 to 2,147,483,647 signed, and 0 to 4,294,967,295 unsigned.

I quoted the standard which is more reliable than testing a compiler (since a compiler can be noncompliant), but since you are so stubborn, the test shows that an int and an unsigned int have the same range as a long on this compiler (which are the ranges I gave earlier in my reply, which is also the range you gave here). Anyway, if the test came out differently, it wouldn't have meant you were right since it is completely valid for a compiler to do that (though on a 32-bit or 64-bit machine it would be pretty stupid for a compiler to do that). It's up to the compiler how they wish to implement it.

Quote:
Original post by sakky
The screwed up thing is, that the int and the long are the same size on my 32 bit processor. But the int STILL can’t even hold the amount of the long because of that standard or some other reason. Because on my machine, sizeof( int ) = 4. And on my friends machine sizeof( int ) = 8. However, sizeof( long ) = 4 on both of ours machines.

Either you have a noncompliant compiler or you are simply lying (sorry to make such an accusation, but I've quoted the standard, tested with the same compiler that you are using, yet you still are claiming these results)!

Since you are continuing on, I will again quote the standard:


1.7
-1-
Quote:
"The fundamental storage unit in the C++ memory model is the byte." ...




5.3.3
-1-
Quote:
"The sizeof operator yields the number of bytes in the object representation of its operand." ...




3.9.1
-2-
Quote:
"There are four signed integer types: ``signed char'', ``short int'', ``int'', and ``long int.'' In this list, each type provides at least as much storage as those preceding it in the list." ...





Since 1.7 declares the fundamental storage unit to be a byte, and 5.3.3 declares the sizeof operator to yield the number of bytes (defined in 1.7 to be the unit of storage) that an instantiation of a type occupies, and 3.9.1 declares that each type in the mentioned list provides at least as much storage (defined in 1.7 as bytes) as the previous one in the list where in comes before long, then that means that sizeof long would always have to yield a value at least as large as sizeof int.

Share this post


Link to post
Share on other sites
I'm with Evil Steve and Polymorphic OOP on this. Except for the fact that Evil Steve shouldn't log in as root. [evil]

sakky - Try this. Note that char, signed char, and unsigned char are actually three different types. All other integral types are signed by default.


#include <iostream>
#include <limits>

int main()
{
std::cout << "char size " << sizeof(char) << std::endl
<< "char min " << std::numeric_limits<char>::min() << std::endl
<< "char max " << std::numeric_limits<char>::max() << std::endl
<< "signed char min " << std::numeric_limits<signed char>::min() << std::endl
<< "signed char max " << std::numeric_limits<signed char>::max() << std::endl
<< "unsigned char min " << std::numeric_limits<unsigned char>::min() << std::endl
<< "unsigned char max " << std::numeric_limits<unsigned char>::max() << std::endl
<< std::endl;

std::cout << "short size " << sizeof(short) << std::endl
<< "short min " << std::numeric_limits<short>::min() << std::endl
<< "short max " << std::numeric_limits<short>::max() << std::endl
<< "unsigned short min " << std::numeric_limits<unsigned short>::min() << std::endl
<< "unsigned short max " << std::numeric_limits<unsigned short>::max() << std::endl
<< std::endl;

std::cout << "int size " << sizeof(int) << std::endl
<< "int min " << std::numeric_limits<int>::min() << std::endl
<< "int max " << std::numeric_limits<int>::max() << std::endl
<< "unsigned int min " << std::numeric_limits<unsigned int>::min() << std::endl
<< "unsigned int max " << std::numeric_limits<unsigned int>::max() << std::endl
<< std::endl;

std::cout << "long size " << sizeof(long) << std::endl
<< "long min " << std::numeric_limits<long>::min() << std::endl
<< "long min " << std::numeric_limits<long>::max() << std::endl
<< "unsigned long min " << std::numeric_limits<unsigned long>::min() << std::endl
<< "unsigned long min " << std::numeric_limits<unsigned long>::max() << std::endl
<< std::endl;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by sakky
int = 4 bytes
long = 4 bytes
Press any key to continue

Is what I get on my system. Why is my machine so weird then? Hmmm, I give up!

Again, that is completely valid. A long has to be at least as big as an int. In your example it gave a 4 and a 4. 4 is greater than or equal to 4. There is nothing weird about your system. Again, this doesn't mean that a long is 4 bytes on any compiler.

Quote:
Original post by Empirical
But wouldnt that imply he's on a 16 bit system? Or are there other reasons for a int being 2 bytes?

sizeof int can be 2 bytes on a 32 bit system, or even on a 64 bit system, or it can even by 1 byte. The most common reason for this is because the C++ standard never guarantees that a byte has to be 8 bits nor that a byte in C++ terms has to be the same thing as a byte in the systems terms. For instance, a char must be at least 8 bits, so there is nothing stopping it from being 16 bits. A char is guaranteed to be 1 byte, which therefore means that the C++ byte on this example compiler is in fact 16 bits (which is a 2 byte value in the systems terms). Since one byte is 16 bits, that means that a 32 bit int can be represented in 2 C++ bytes on this compiler. Therefore, sizeof int can yield 2 bytes, which is still a 32 bit integer and can hold just as much a a 32 bit int on a system which yields 4 bytes with a byte defined to be 8 bits (assuming they both use the same way of representing signed integers, most-likely 2s compliment).

Share this post


Link to post
Share on other sites
Quote:
Original post by sakky
int = 4 bytes
long = 4 bytes
Press any key to continue

Is what I get on my system. Why is my machine so weird then? Hmmm, I give up!

Because your system is 32-bits :P Or the compiler is

Quote:
Original post by Fruny
Except for the fact that Evil Steve shouldn't log in as root.

Actually, it was Pouya's machine. Blame him :P

Share this post


Link to post
Share on other sites
Quote:
Original post by Empirical
Polymorphic OOP>
Ah I see. But he also says that on his system an int holds 0-65535 (unsigned). That implies a 16 bit value. But why unless he is on a 16bit platform?


ints aren't necessarily in 2s compliment format, so you aren't guaranteed that 32 bits can hold 2^32 different values. For instance, if an implementation instead used a signed bit, it would have 2^32 - 1 values it could represent (since it would have a positive and negative 0), and conceivably, some off-the-wall implementation could represent an even smaller range (or a shifted range), though it would be highly unlikely. Of course, in practice it would be tough to find an example of these situations, but it is important to note that the standard does leave it open as a possibility, and as such, you still can make no assumptions. A 32 bit int's range is never defined. Since his int can hold that range, it's extremely likely that he is running a 16 bit machine with a compiler that represents an int with 16 bits in 2s compliment form, but that is not guaranteed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
I'm with Evil Steve and Polymorphic OOP on this. Except for the fact that Evil Steve shouldn't log in as root. [evil]

sakky - Try this. Note that char, signed char, and unsigned char are actually three different types. All other integral types are signed by default.

*** Source Snippet Removed ***

I should point out that while char, signed char, and unsigned char are all different types, they are guaranteed to be the same size by the standard.

Share this post


Link to post
Share on other sites
Quote:
Original post by Washu
Quote:
Original post by Fruny
I'm with Evil Steve and Polymorphic OOP on this. Except for the fact that Evil Steve shouldn't log in as root. [evil]

sakky - Try this. Note that char, signed char, and unsigned char are actually three different types. All other integral types are signed by default.

*** Source Snippet Removed ***

I should point out that while char, signed char, and unsigned char are all different types, they are guaranteed to be the same size by the standard.

they are? i thought char would default to either unsigned char or signed char, just like int.

also why would you bother to have a signed char anyway?
what ASCII or UNICODE characters use -1 or less?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this