Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > On what does size of data types depend?

Reply
Thread Tools

On what does size of data types depend?

 
 
Eric Sosman
Guest
Posts: n/a
 
      10-05-2005


Skarmander wrote On 10/05/05 10:30,:
> Eric Sosman wrote:
>
>>Sunil wrote:
>>
>>> printf("char : %d\n",sizeof(char));
>>> [...]

>>
>> On some systems I have used, the output would claim
>>that all the types are of size zero. Hint: What type of
>>value does "%d" expect, and what type of value does sizeof
>>produce?
>>

> <snip>
> What exactly *is* the format specifier for size_t in C90? C99 has "%zu",
> but is (say) "%lu" guaranteed to work?


The usual C90 way is

printf ("size = %lu\n", (unsigned long)sizeof(Type));

This works because size_t must be an unsigned integer type,
C90 has only four such types, and unsigned long can handle
all the values of any of the four.

In C99 the number of unsigned integer types is much
larger, and varies from one implementation to another. The
widest unsigned integer type is uintmax_t, so one could
write (using another C99-invented length modifier)

printf ("size = %ju\n", (uintmax_t)sizeof(Type));

I do not know for sure why the committee decided to
invent the "z" width modifier, but two motivations seem
plausible:

- That silly cast is a pain, and since other length
modifiers were already being invented it was easy
to introduce a new one for size_t.

- On small machines size_t might be as narrow as 16
bits, while uintmax_t must be at least 64 bits.
Working with 64-bit values might require a multi-
precision software library that would otherwise
not be needed. The "z" modifier lets one avoid
using uintmax_t, and might allow the implementation
to exclude the unnecessary library (recall systems
that tried to omit software floating-point support
when they thought the program wouldn't use it.)

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Skarmander
Guest
Posts: n/a
 
      10-05-2005
Eric Sosman wrote:
>
> Skarmander wrote On 10/05/05 10:30,:
>
>>Eric Sosman wrote:
>>
>>
>>>Sunil wrote:
>>>
>>>
>>>> printf("char : %d\n",sizeof(char));
>>>>[...]
>>>
>>> On some systems I have used, the output would claim
>>>that all the types are of size zero. Hint: What type of
>>>value does "%d" expect, and what type of value does sizeof
>>>produce?
>>>

>>
>><snip>
>>What exactly *is* the format specifier for size_t in C90? C99 has "%zu",
>>but is (say) "%lu" guaranteed to work?

>
>
> The usual C90 way is
>
> printf ("size = %lu\n", (unsigned long)sizeof(Type));
>
> This works because size_t must be an unsigned integer type,
> C90 has only four such types, and unsigned long can handle
> all the values of any of the four.
>

<snip>
> I do not know for sure why the committee decided to
> invent the "z" width modifier, but two motivations seem
> plausible:

<snip>

I'm guessing because it offers a valuable abstraction. The argument by
elimination one has to apply for C90 is shaky: a future implementation
that uses 64-bit size_t's but 32-bit longs (and 64-bit long longs,
presumably) will find its format specifiers outdated.

After all, there's a reason size_t wasn't just defined as "unsigned
long", and the format specifiers should allow for it.

S.
 
Reply With Quote
 
 
 
 
Simon Biber
Guest
Posts: n/a
 
      10-05-2005
Skarmander wrote:
> Eric Sosman wrote:
> <snip>
>
>> I do not know for sure why the committee decided to
>> invent the "z" width modifier, but two motivations seem
>> plausible:

>
> <snip>
>
> I'm guessing because it offers a valuable abstraction. The argument by
> elimination one has to apply for C90 is shaky: a future implementation
> that uses 64-bit size_t's but 32-bit longs (and 64-bit long longs,
> presumably) will find its format specifiers outdated.


The point is, C90 and C99 are different languages, and correct code on
one is not necessarily correct code on the other. Pick one of the two,
and set up your compiler options to match that choice.

If you are writing C90 code, there cannot be any integer type larger
than unsigned long. Therefore, casting size_t to unsigned long must
preserve the correct value. Any implementation that has 64-bit size_t
but 32-bit long DOES NOT CONFORM TO C90.

If you are writing for C99, then you should be using the %zu specifier
and not trying to cast to unsigned long.

--
Simon.
 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      10-05-2005
Simon Biber wrote:
> Skarmander wrote:
>
>> Eric Sosman wrote:
>> <snip>
>>
>>> I do not know for sure why the committee decided to
>>> invent the "z" width modifier, but two motivations seem
>>> plausible:

>>
>>
>> <snip>
>>
>> I'm guessing because it offers a valuable abstraction. The argument by
>> elimination one has to apply for C90 is shaky: a future implementation
>> that uses 64-bit size_t's but 32-bit longs (and 64-bit long longs,
>> presumably) will find its format specifiers outdated.

>
>
> The point is, C90 and C99 are different languages, and correct code on
> one is not necessarily correct code on the other. Pick one of the two,
> and set up your compiler options to match that choice.
>
> If you are writing C90 code, there cannot be any integer type larger
> than unsigned long. Therefore, casting size_t to unsigned long must
> preserve the correct value. Any implementation that has 64-bit size_t
> but 32-bit long DOES NOT CONFORM TO C90.
>

Oh, that's a good point. An implementation wouldn't be allowed to do
that in C90 mode even if it could.

That is, I think. The standard *is* worded in such a way that makes it
impossible for size_t to be an integral type different from unsigned
char, short, int, long, right? It'll say something like "the integral
types are such and such" and "size_t must be an unsigned integral type",
so that size_t is always convertible to an unsigned long without loss.

> If you are writing for C99, then you should be using the %zu specifier
> and not trying to cast to unsigned long.
>

Yes, but that wasn't exactly the point. The question was why C99 added
it in the first place. And in my opinion, this was to settle the matter
once and for all. Had C99 not added "%zu", then C99 would be subject to
the same problem, possibly limiting the implementation artifically. C90
needs %lu, C99 would have needed %llu, etc. (Not that I imagine that
many successors to C99 which will boost the ranges of integral types,
but you get the point.)

The comparison here is not between C90 and C99, but between C99 and its
hypothetical successor. The "just use the specifier for the biggest
integer in the language" approach is not stable (and not clean), and the
simple introduction of a new specifier to cover the abstraction solves
this issue now and forever.

S.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-05-2005
John Devereux <(E-Mail Removed)> writes:
> "Sunil" <(E-Mail Removed)> writes:
>
>> Hi all,
>>
>> I am using gcc compiler in linux.I compiled a small program
>> int main()
>> {
>> printf("char : %d\n",sizeof(char));
>> printf("unsigned char : %d\n",sizeof(unsigned char));
>> printf("short : %d\n",sizeof(short));

>
> <SNIP>
>
> This brings to mind something that I have wondered about.
>
> I often see advice elsewhere, and in other peoples programs,
> suggesting hiding all C "fundamental" types behind typedefs such as
>
> typedef char CHAR;
> typedef int INT32;
> typedef unsigned int UINT32;
> typedef char* PCHAR;
>
> The theory is that application code which always uses these typedefs
> will be more likely to run on multiple systems (provided the typedefs
> are changed of course).
>
> I used to do this. Then I found out that C99 defined things like
> "uint32_t", so I started using these versions instead. But after
> following this group for a while I now find even these ugly and don't
> use them unless unavoidable.


Of the typedefs above, I'd have to say that CHAR and PCHAR are utterly
useless. Presumably there's never any reason to define CHAR as
anything other than char, or PCHAR as anything other than char*. If
so, just use char and char* directly, so the reader doesn't have to
wonder if CHAR and PCHAR have been defined properly. If not, the
names CHAR and PCHAR are misleading.

As for INT32 and UINT32, of course those definitions will have to be
changed for systems where int and unsigned int are something other
than 32 bits. C99, as you've seen, provides int32_t and uint32_t in
<stdint.h>. If you don't have a C99 compiler, you can define them
yourself. Doug Gwyn has written a public domain implementation of
some of the new C99 headers for use with C90; see
<http://www.lysator.liu.se/c/q8/>.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      10-05-2005
Skarmander a écrit :
> What exactly *is* the format specifier for size_t in C90? C99 has "%zu",
> but is (say) "%lu" guaranteed to work?


Yes, with (unsigned long).
 
Reply With Quote
 
Christian Bau
Guest
Posts: n/a
 
      10-05-2005
In article <(E-Mail Removed) .com>,
"Sunil" <(E-Mail Removed)> wrote:

> What i want to know is what will be the effect if i use int in
> place of long in applications running on linux and also on what factors
> does the size of datatypes depend.


int is guaranteed to be capable of holding values in the range -32767 to
+32767, nothing else. You can use int of your data is in that range.

long is guaranteed to be capable of holding values in the range from
about -2,000,000,000 to +2,000,000,000. Use long if your data can be
outside the range guaranteed to be available for int, but not outside
the larger range.

Size of datatypes depends on whatever the compiler writer thought was a
good idea. Don't be surprised if sizeof (long) or sizeof (void *) is
greater than four.
 
Reply With Quote
 
Christian Bau
Guest
Posts: n/a
 
      10-05-2005
In article <(E-Mail Removed)>,
John Devereux <(E-Mail Removed)> wrote:

> I often see advice elsewhere, and in other peoples programs,
> suggesting hiding all C "fundamental" types behind typedefs such as
>
> typedef char CHAR;
> typedef int INT32;
> typedef unsigned int UINT32;
> typedef char* PCHAR;
>
> The theory is that application code which always uses these typedefs
> will be more likely to run on multiple systems (provided the typedefs
> are changed of course).
>
> I used to do this. Then I found out that C99 defined things like
> "uint32_t", so I started using these versions instead. But after
> following this group for a while I now find even these ugly and don't
> use them unless unavoidable.


typedef char CHAR; and typedef char* PCHAR; is just plain stupid.

"int", "long" etc. , properly used, is the best way to code. However,
they are often not properly used, and there will be lots of trouble
because of that when 64 bit systems become more widely available. If you
use a typedef like INT32 or uint32_t, at least I know what assumptions
you made.
 
Reply With Quote
 
Christian Bau
Guest
Posts: n/a
 
      10-05-2005
In article <4343e39e$0$11073$(E-Mail Removed)4all.nl>,
Skarmander <(E-Mail Removed)> wrote:

> Eric Sosman wrote:
> > Sunil wrote:
> >
> >> Hi all,
> >>
> >> I am using gcc compiler in linux.I compiled a small program
> >> int main()
> >> {
> >> printf("char : %d\n",sizeof(char));
> >> printf("unsigned char : %d\n",sizeof(unsigned char));
> >> printf("short : %d\n",sizeof(short));
> >> printf("unsigned short : %d\n",sizeof(unsigned short));
> >> printf("int : %d\n",sizeof(int));
> >> printf("unsigned int : %d\n",sizeof(unsigned int));
> >> printf("long : %d\n",sizeof(long));
> >> printf("unsigned long : %d\n",sizeof(unsigned long));
> >> printf("long long : %d\n",sizeof(long long));
> >> printf("unsigned long long : %d\n",sizeof(unsigned long
> >> long));
> >> }

> >
> >
> > On some systems I have used, the output would claim
> > that all the types are of size zero. Hint: What type of
> > value does "%d" expect, and what type of value does sizeof
> > produce?
> >

> <snip>
> What exactly *is* the format specifier for size_t in C90? C99 has "%zu",
> but is (say) "%lu" guaranteed to work?


printf("short: %lu\n", (unsigned long) sizeof(short));

will work as long as a short is fewer than four billion bytes

(I remember seeing a bug while a program was being ported: A function
took an argument of type long, and the value passed was "- sizeof
(short)". The function received a value of 65534 which was a bit
unexpected. And yes, the compiler was right. )
 
Reply With Quote
 
Alexei A. Frounze
Guest
Posts: n/a
 
      10-05-2005
"Christian Bau" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
....
> printf("short: %lu\n", (unsigned long) sizeof(short));
>
> will work as long as a short is fewer than four billion bytes


Correct

> (I remember seeing a bug while a program was being ported: A function
> took an argument of type long, and the value passed was "- sizeof
> (short)". The function received a value of 65534 which was a bit
> unexpected. And yes, the compiler was right. )


C is wonderful in this respect. Perhaps because of this Java AFAIK has no
unsigned types.

Alex


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Preferred Size, Minimum Size, Size Jason Cavett Java 5 05-25-2008 08:32 AM
mega pixels, file size, image size, and print size - Adobe Evangelists Frank ess Digital Photography 0 11-14-2006 05:08 PM
equivalent c data types for vc++ data types ramu C Programming 2 02-20-2006 09:33 AM
size of a class having enumerated data types? ypjofficial@indiatimes.com C++ 8 01-23-2006 12:29 PM
Size of data types in C? siliconwafer C Programming 12 10-11-2005 03:35 PM



Advertisments