coding style advice for sizeof (long) < sizeof (size_t)? 
Author Message
 coding style advice for sizeof (long) < sizeof (size_t)?

There still seems to be considerable controversy about the quiet change
in C9x that allows sizeof (long) to be less than sizeof (size_t), so I
am thinking of proposing the following text for addition to the GNU
coding standards.  Comments?

        ------------------------------
        To convert an object size to a printable representation,
        convert it to unsigned long first.  E.g.:

           int array[ARRAY_ITEMS];
           printf ("The array has %lu bytes.\n", (unsigned long) sizeof array);

        The draft of the next C standard (C9x) allows hosts where this
        method might not work because `unsigned long' might be too
        small to hold an object's size.  Don't make any effort to cater
        to this possibility; it's not worth the trouble.

        However, system types other than size_t are not necessarily
        convertible with this method.  For example, off_t is longer
        than long on some hosts, so it's not safe to print an off_t
        value with %ld.  One portable way to print an off_t value is to
        convert it by hand to a decimal string, and then print the string.

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

The GNU folks are big on portable programming, but only within limits.
For example, the current GNU coding standard says ``don't make any
effort to cater to the possibility that an `int' will be less than 32
bits.  We don't support 16-bit machines in GNU.'' The text proposed
above attempts to be in a similar spirit.



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

>There still seems to be considerable controversy about the quiet change
>in C9x that allows sizeof (long) to be less than sizeof (size_t), so I
>am thinking of proposing the following text for addition to the GNU
>coding standards.  Comments?

>    ------------------------------
>    To convert an object size to a printable representation,
>    convert it to unsigned long first.  E.g.:

>       int array[ARRAY_ITEMS];
>       printf ("The array has %lu bytes.\n", (unsigned long) sizeof array);

>    The draft of the next C standard (C9x) allows hosts where this
>    method might not work because `unsigned long' might be too
>    small to hold an object's size.  Don't make any effort to cater
>    to this possibility; it's not worth the trouble.

I think that's reasonable.  Only utterly perverse implementations will
not obey that one.

Quote:
>    However, system types other than size_t are not necessarily
>    convertible with this method.  For example, off_t is longer
>    than long on some hosts, so it's not safe to print an off_t
>    value with %ld.  One portable way to print an off_t value is to
>    convert it by hand to a decimal string, and then print the string.

The 'official' C9X solution is to use intmax_t, which is fine if you
can assume C9X.  But I shan't be doing so before about 2003, even if
C9X is accepted.

There is a much better, and simpler, solution.  Convert it to double
and print it using %.0f.  Care should be taken with this when it is
critical that the value is exact even for the largest numbers, but
that is rarely the case.  Up to about 7 years ago, compilers which
had broken unsigned->double conversions were pretty common, but I
haven't seen one recently.  The standard specifies only 9 digits,
but you can reasonably assume 15.

The next simplest solution is the following:

    if (value >= 1000000000)
        printf("%ld%.9ld",value/1000000000,value%1000000000);
    else
        printf("%ld,value);

This works in everything from K&R to C9X for numbers up to
10^9*LONG_MAX.  If you really HAVE to display EVERY number perfectly,
then there is no alternative but to do the job properly.

Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.

Tel.:  +44 1223 334761    Fax:  +44 1223 334679



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

>There still seems to be considerable controversy about the quiet change
>in C9x that allows sizeof (long) to be less than sizeof (size_t), so I
>am thinking of proposing the following text for addition to the GNU
>coding standards.  Comments?

I sometimes use "compile time assertions" of the form:

        extern int dummy_xxx[TEST ? 1 : -1];

where the compiler will shout {*filter*}y {*filter*} about a negative array size
if the compile time constant TEST isn't true.  (A test like if two
arrays have the same number of initializers.)  I'm planning on adding
this to code that prints size_t using the usual cast to unsigned long:

  extern int dummy_size_t_check[sizeof(size_t) <= sizeof(long) ? 1 : -1];

I regularly write code that works on 16 and 32-bit machines, with the
programs on the 32-bit machine handling the bigger input that those
machines naturally tend to bring forth.  So I fully expect machines with
64-bit size_t to present input to my old programs that is similarly
larger than 32-bit machines can handle.
--
Kees J. Bot, Systems Programmer, Sciences dept., Vrije Universiteit Amsterdam



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

(snip)

Quote:

> The next simplest solution is the following:

>     if (value >= 1000000000)
>         printf("%ld%.9ld",value/1000000000,value%1000000000);

that should be:

          printf("%ld%09.9ld",value/1000000000,value%1000000000);

So that the two parts of the number will always fit together properly.

Quote:
>     else
>         printf("%ld,value);

> This works in everything from K&R to C9X for numbers up to
> 10^9*LONG_MAX.  If you really HAVE to display EVERY number perfectly,
> then there is no alternative but to do the job properly.

--
 __  __  _                                      
 _ ) ___ _\   Enterprise Middleware Solutions   Darron J Shaffer
 __) __    \  BEA Systems Inc.                  Sr. Software Engineer

              4965 Preston Park Blvd, Ste 500   Voice: (972) 943-5137    
              Plano, TX 75093                   Fax:   (972) 943-5111    
              http://www.beasys.com


Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

>The next simplest solution is the following:

>    if (value >= 1000000000)
>        printf("%ld%.9ld",value/1000000000,value%1000000000);
>    else
>        printf("%ld,value);

>This works in everything from K&R to C9X for numbers up to
>10^9*LONG_MAX.  If you really HAVE to display EVERY number perfectly,
>then there is no alternative but to do the job properly.

Why does this work in C9X?  I would assume that if value is of type long
long, the two expressions involving value are also of type long long.  If
long long has a representation different from long, why should we expect %ld
to work?

Suppose value is 'int' on an I32L64 system?  This fails even on C89 systems.



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

> >         printf("%ld%.9ld",value/1000000000,value%1000000000);

> that should be:

>           printf("%ld%09.9ld",value/1000000000,value%1000000000);

Exactly what is it that you think "%09.9ld" does differently than
"%.9ld"?

-Larry Jones

He just doesn't want to face up to the fact that I'll be
the life of every party. -- Calvin



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?


Quote:

> > >         printf("%ld%.9ld",value/1000000000,value%1000000000);

> > that should be:

> >           printf("%ld%09.9ld",value/1000000000,value%1000000000);

> Exactly what is it that you think "%09.9ld" does differently than
> "%.9ld"?

It zero-pads the field.

--
Richard Heathfield

"The bug stops here."



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

> The 'official' C9X solution is to use intmax_t, which is fine if you
> can assume C9X.  But I shan't be doing so before about 2003, even if
> C9X is accepted.

To the contrary, the GNU coding standards should encourage the use
of <stdint.h> and/or <inttypes.h>.  There is no need to wait for
C9x; these headers can be and have been implemented for C89
implementations; it's almost trivial.  GCC ought to provide these
*now*, but if they don't, the porter can readily provide his own.

Advice to cast to unsigned long and ignore future problems is what
got people like Peter Curran into trouble in the first place!



Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

> I sometimes use "compile time assertions" of the form:
>         extern int dummy_xxx[TEST ? 1 : -1];
> where the compiler will shout {*filter*}y {*filter*} about a negative array size
> if the compile time constant TEST isn't true.  (A test like if two
> arrays have the same number of initializers.)  I'm planning on adding
> this to code that prints size_t using the usual cast to unsigned long:
>   extern int dummy_size_t_check[sizeof(size_t) <= sizeof(long) ? 1 : -1];
> I regularly write code that works on 16 and 32-bit machines, with the
> programs on the 32-bit machine handling the bigger input that those
> machines naturally tend to bring forth.  So I fully expect machines with
> 64-bit size_t to present input to my old programs that is similarly
> larger than 32-bit machines can handle.

You are taking a convoluted approach to this, which may not
even work as you expect on some implementations.
Why not simply write code that works properly on all platforms?


Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:
> the GNU coding standards should encourage the use
> of <stdint.h> and/or <inttypes.h>.

I have long advocated <inttypes.h> in the GNU world, and I have written
much of the GNU code that deals with goofball implementations
where `long' cannot store important integer system types.
However, I am starting to reconsider my position,
because it is such a neverending hassle to port to such systems.
Now that my usual platform (Solaris sparc) finally supports LP64,
I'm starting to think that it may be better to stop catering to the goofballs.

Furthermore, even if I wanted to, I doubt whether I could get the
GNU coding standards to recommend <inttypes.h> or <stdint.h>.
Generally speaking, GNU code prefers to use `int' for integers.
This keeps the code simple, and is more in the original spirit of C.
Of course sometimes other integer types need to be used for portability's sake,
but in general the GNU style has proved to be quite portable in the past,
and I doubt whether it will change any time soon.

Quote:
>GCC ought to provide these *now*

Please feel free to contribute implementations.
You can get a recent copy of the GCC source from http://egcs.cygnus.com/.
I think it would be helpful if someone who understands those headers
would propose a specific patch that would implement them.

The GCC source code mentions intmax_t in a few places now, because
I wrote that intmax_t code, back when I had more time to contribute to GCC.
This caused quite a few porting hassles,
and I don't blame the other implementers for not continuing the job:
they've got more important things to do.
The only way this stuff gets done is if someone steps up to volunteer.

Quote:
>Advice to cast to unsigned long and ignore future problems is what
>got people like Peter Curran into trouble in the first place!

I don't think anybody _likes_ `printf ("%lu", (unsigned long) sizeof x)';
its only redeeming quality is that it's simpler and more portable
than the alternatives.  C9x won't change this.


Mon, 17 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?


Quote:





> > > > >         printf("%ld%.9ld",value/1000000000,value%1000000000);

> > > > that should be:

> > > >           printf("%ld%09.9ld",value/1000000000,value%1000000000);

> > > Exactly what is it that you think "%09.9ld" does differently than
> > > "%.9ld"?

> > It zero-pads the field.

> The precision .9 already forces leading zeroes to a width of 9.

Oh yeah! (Learn something new every day)

I spent about 2 minutes trying to think of a witty way out of this one -
you'll be glad to hear that I failed. So,

You are correct.
Thank you for the correction.

Anyone got a fast algorithm for generating humble pi?

--
Richard Heathfield

"The bug stops here."



Tue, 18 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?


Quote:
>>    if (value >= 1000000000)
>>        printf("%ld%.9ld",value/1000000000,value%1000000000);
>>    else
>>        printf("%ld,value);
>Why does this work in C9X?  I would assume that if value is of type long
>long, the two expressions involving value are also of type long long.  If
>long long has a representation different from long, why should we expect %ld
>to work?

Indeed. However, it's easy enough to fix:

    if (value >= 1000000000)
        printf("%lu%.9lu", (unsigned long) (value/1000000000),
                           (unsigned long) (value%1000000000));
    else
        printf("%lu, (unsigned long) value);

--


Fax: +44 181 371 1037 | Demon Internet Ltd.    | Web:  <http://www.davros.org>
Written on my laptop; please observe the Reply-To address



Tue, 18 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?


Quote:

>Advice to cast to unsigned long and ignore future problems is what
>got people like Peter Curran into trouble in the first place!

Doug, until this comment I'd been feeling pretty ambivalent; I agreed
with Peter and others that about the "long is no longer the longest
type" change being a bad thing, but I'd sympathized with the Committee
being stuck and having to make a choice.

But the above is a blatant rewrite of reality. The Committee
*explicitly* told Peter and the rest of us to cast to unsigned long, as
that was what the standard guaranteed. No mention of future problems
or an intention to change that guarantee. Yeah, we knew the standard
would change, but the "long is the longest" guarantee seemed pretty
fundamental, almost as sacred as "sizeof(char) == 1"

Well, we were wrong, and we'll try to deal. But for you to imply that
"assume unsigned long is the longest type" is advice equivalent to
"assume sizeof(int)==4" (as I think you do in your statement) is unfair,
misleading, and mean. I've been lurking around comp.std.c for quite a
while, and you're one of the reasons it's been worthwhile. I'm hoping
that the above statement was a momentary aberration.

Steve Greenland
--
The Mole - I think, therefore I scream

                                "Merry Christmas, scumwad."
[Norm Buntz's jolly wish to Belker's assailant on HILL STREET BLUES]



Tue, 18 Sep 2001 03:00:00 GMT  
 coding style advice for sizeof (long) < sizeof (size_t)?

Quote:

>am thinking of proposing the following text for addition to the GNU
>coding standards.  Comments?
>------------------------------
>To convert an object size to a printable representation,
>convert it to unsigned long first.  E.g.:
>   int array[ARRAY_ITEMS];
>   printf ("The array has %lu bytes.\n", (unsigned long) sizeof array);
>The draft of the next C standard (C9x) allows hosts where this
>method might not work because `unsigned long' might be too
>small to hold an object's size.  Don't make any effort to cater
>to this possibility; it's not worth the trouble.

Wrong.  The reason this issue hasn't disappeared is that the committee
indeed has reasons for standardizing this possibility:  vendors will
indeed make implementations with this feature, because customers demand
it.  So it's not a matter of not being worth the trouble.  GNU will die
if they don't cater to it.

How's this:
To convert an object size to a printable representation, convert
it to a printable integral type.  Use config to find the type.

Quote:
>One portable way to print an off_t value is to
>convert it by hand to a decimal string, and then print the string.

Hmm, true.  But wait a minute, GNU is in charge of gcc.  Not only can
GNU write an entire library to replace the vendor's printf(), GNU can
also define long as the longest possible integral type.  Problem solved.

Quote:
>The GNU folks are big on portable programming, but only within limits.

Yeah, big but small :-)

Quote:
>For example, the current GNU coding standard says ``don't make any
>effort to cater to the possibility that an `int' will be less than 32
>bits.  We don't support 16-bit machines in GNU.'' The text proposed
>above attempts to be in a similar spirit.

Yes your proposal is similar in spirit.

One more possibility:  "We don't support 64-bit machines in GNU either."

Best possibility:  GNU could figure out whether it likes portability.
By the way, what is GNU's opinion of djgpp?

--
 <<  If this were the company's opinion, I would not be allowed to post it.  >>
"I paid money for this car, I pay taxes for vehicle registration and a driver's
license, so I can drive in any lane I want, and no innocent victim gets to call
the cops just 'cause the lane's not goin' the same direction as me" - J Spammer



Tue, 18 Sep 2001 03:00:00 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. sizeof(int) sizeof(long) etc.

2. (char *)malloc((size_t)(1*sizeof(char)))

3. relation between sizeof(void*), sizeof(int)

4. sizeof (struct) ! = sizeof struct elements

5. sizeof without sizeof

6. sizeof a/sizeof *a

7. sizeof(foo) -1 or sizeof(foo)

8. sizeof(void*) versus sizeof(foo*)

9. Basic question on sizeOf variables int, long

10. sizeof(long double)

11. Relationship between sizeof(unsigned long) and ULONG_MAX

12. Sizeof(long/int/char) on Crays

 

 
Powered by phpBB® Forum Software