Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

itoa() in C for unix >>>

230 views
Skip to first unread message

nad...@topaz.cqu.edu.au

unread,
Apr 12, 1996, 3:00:00 AM4/12/96
to
Hi,

Does anyone have or know of where I may obtain a itoa()
integer to string function in C/C++; my Linux box
doesn't have one and I could use it right now.

Please direct email reply to nad...@topaz.cqu.edu.au

++thanks == TIA

Rob -


P.Bennett

unread,
Apr 12, 1996, 3:00:00 AM4/12/96
to
In article <1996Apr12.121207@topaz>, nad...@topaz.cqu.edu.au writes...

>Hi,
>
>Does anyone have or know of where I may obtain a itoa()
>integer to string function in C/C++; my Linux box
>doesn't have one and I could use it right now.

try using sprintf()

Peter Bennett VE7CEI | Vessels shall be deemed to be in sight
Internet: ben...@triumf.ca | of one another only when one can be
Packet: ve7cei@ve7kit.#vanc.bc.ca | observed visually from the other
TRIUMF, Vancouver, B.C., Canada | ColRegs 3(k)
GPS and NMEA info and programs: ftp://sundae.triumf.ca/pub/peter/index.html
or: ftp://ftp-i2.informatik.rwth-aachen.de/pub/arnd/GPS/peter/index.html


John Hobson

unread,
Apr 15, 1996, 3:00:00 AM4/15/96
to
nad...@topaz.cqu.edu.au wrote:
>Does anyone have or know of where I may obtain a itoa()
>integer to string function in C/C++; my Linux box
>doesn't have one and I could use it right now.

Two solutions: use sprintf, or else look in Kernighan & Ritchie, where
they give an itoa() function as an exercise.

--
John Hobson | The Mahatma Gandhi was once asked, "Mr
Unix Support Group | Gandhi, what do you think of Western
Commonwealth Edison, Chicago, IL | Civilization?" He replied, "I think
jho...@ceco.ceco.com | that it would be an excellent idea."


Dieter Lücking

unread,
Apr 15, 1996, 3:00:00 AM4/15/96
to
> >Does anyone have or know of where I may obtain a itoa()
> >integer to string function in C/C++; my Linux box
> >doesn't have one and I could use it right now.
>
> Two solutions: use sprintf, or else look in Kernighan & Ritchie, where
> they give an itoa() function as an exercise.

Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa().

Isn't it a foolish name: _itoa()
Dieter


The Amorphous Mass

unread,
Apr 15, 1996, 3:00:00 AM4/15/96
to
On Mon, 15 Apr 1996, Dieter L=FCcking wrote:

> > >Does anyone have or know of where I may obtain a itoa()
> > >integer to string function in C/C++; my Linux box
> > >doesn't have one and I could use it right now.

> >=20


> > Two solutions: use sprintf, or else look in Kernighan & Ritchie, where
> > they give an itoa() function as an exercise.

>=20
> Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa(=
).

According to whom? _itoa() is not ANSI either. It looks like compiler=
=20
glue. Use sprintf(), which _is_ ANSI.

--
James Robinson "Because we are returning a copy for postfix ++=
=20
james-r...@uiowa.edu expressions, statements such as (c++)++; won't
robi...@cs.uiowa.edu work as expected." -- Weiskamp & Flami=
g,
_The_Complete_C++_Primer_, 2nd e=
d.


Larry Jones

unread,
Apr 17, 1996, 3:00:00 AM4/17/96
to
In article <3172B3...@braunschweig.netsurf.de>, Dieter Lücking <luec...@braunschweig.netsurf.de> writes:
> Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa().

No, it's not. There are *no* ANSI/ISO standard names that begin with
an underscore -- such names are generally reserved for implementation-
specific things.
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH 45150-2789 513-576-2070
larry...@sdrc.com
If I was being raised in a better environment, I wouldn't
do things like that. -- Calvin

Guy Dallaire

unread,
Apr 18, 1996, 3:00:00 AM4/18/96
to
nad...@topaz.cqu.edu.au wrote:

>Hi,

>Does anyone have or know of where I may obtain a itoa()

If you really can't find it, use sprintf instead...

Ex.: sprintf(szString, "%d", iValue);

This will place the string version of iValue into szString. You can
use all of printf's flags too.

Hope this helps
Guy Dallaire
Groupe DMR Inc.
dall...@megatoon.com

P.S. My opinions are my own and do not reflect those of my employer


Jutta Degener

unread,
Apr 18, 1996, 3:00:00 AM4/18/96
to
larry...@sdrc.com (Larry Jones) writes:

>In article <3172B3...@braunschweig.netsurf.de>, Dieter Luecking


>> <luec...@braunschweig.netsurf.de> writes:
>> Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa().
>
> No, it's not. There are *no* ANSI/ISO standard names that begin with
> an underscore -- such names are generally reserved for implementation-
> specific things.

Note that the character at the beginning of __LINE__, __FILE__, and
__STDC__, while frequently typeset as an underscore, is actually an
extremely lower-case dash.

(But, yes, the bit about _itoa being ANSI is nonsensical, and Larry is
right as far as function names are concerned.)

Jutta

Lawrence Kirby

unread,
Apr 18, 1996, 3:00:00 AM4/18/96
to
In article <4l35f4$q...@info1.sdrc.com> larry...@sdrc.com "Larry Jones" writes:

>In article <3172B3...@braunschweig.netsurf.de>, Dieter Lcking


> <luec...@braunschweig.netsurf.de> writes:
>> Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa().
>
>No, it's not. There are *no* ANSI/ISO standard names that begin with
>an underscore -- such names are generally reserved for implementation-
>specific things.

Well, other than _IOFBF, _IOLBF and _IONBF.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

Mike Rubenstein

unread,
Apr 18, 1996, 3:00:00 AM4/18/96
to
larry...@sdrc.com (Larry Jones) wrote:

> In article <3172B3...@braunschweig.netsurf.de>, Dieter Lücking <luec...@braunschweig.netsurf.de> writes:
> > Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa().
>
> No, it's not. There are *no* ANSI/ISO standard names that begin with
> an underscore -- such names are generally reserved for implementation-
> specific things.

Right about _itoa, but there are ANSI/ISO standard names that begin
with an underscore. Examples: __DATE__, _IOFBF.


Michael M Rubenstein

Bertram Wooster

unread,
Apr 20, 1996, 3:00:00 AM4/20/96
to

For the record, when I needed this function I searched *all over*
my system and couldn't find it. I ended up using the function as
defined in K&R's C Prog. Lang. (2nd ed.). Your way is better!


John Hobson

unread,
Apr 22, 1996, 3:00:00 AM4/22/96
to
ber...@Sigma.Epsilon.Chi.org (Bertram Wooster) wrote:
>In article <4l44mv$g...@news.accent.net>, dall...@megatoon.com (Guy Dallaire) says:
>>
>>nad...@topaz.cqu.edu.au wrote:
>>
>>>Hi,
>>
>>>Does anyone have or know of where I may obtain a itoa()
>>
>>If you really can't find it, use sprintf instead...
>>
>>Ex.: sprintf(szString, "%d", iValue);
>>
>>This will place the string version of iValue into szString. You can
>>use all of printf's flags too.
>>
>> Hope this helps
>>Guy Dallaire
>>Groupe DMR Inc.
>>dall...@megatoon.com
>
>For the record, when I needed this function I searched *all over*
>my system and couldn't find it. I ended up using the function as
>defined in K&R's C Prog. Lang. (2nd ed.). Your way is better!
>

If your C standard I/O library does not have sprintf(3S), then complain LOUD
and
LONG to whoever supplied your compiler.

First, look in your manual under printf(3S). Or try "man printf". If you do
not see sprintf there, then I would wonder how many other library functions
might be missing. There is so much C code, going back to the first edition of
K&R, that depends on sprintf that any C compiler which does not have it is so
non-standard as to be essentially useless.

Lawrence Kirby

unread,
Apr 27, 1996, 3:00:00 AM4/27/96
to

In article <fwvd950...@emerald.aifh.ed.ac.uk>
andr...@ed.ac.uk "Andrew Fitzgibbon" writes:

>
>In article <3172B3...@braunschweig.netsurf.de> Dieter Lcking


> <luec...@braunschweig.netsurf.de> writes:
>
>> > >Does anyone have or know of where I may obtain a itoa()

>> > >integer to string function in C/C++; my Linux box
>> > >doesn't have one and I could use it right now.
>> >

>> > Two solutions: use sprintf, or else look in Kernighan & Ritchie, where
>> > they give an itoa() function as an exercise.
>>

>> Notice: itoa() is NOT ANSI, however _itoa() is ANSI. Thus look for _itoa().

ANSI does not define any _itoa() function.

>itoa is hard to standardize because it must either call malloc (core leak),
>alloca (non-ansi), or return a pointer to static storage (just plain
>nasty). All have problems with the following statement
> char *s = strcat(strcat(mystr, itoa(1)), itoa(2));

The obvious solution is to take the sprintf approach where you pass the
function a pointer to a suitable buffer where it can place the resulting
string. This would also allow you to build the output directly into strings
in the target buffer. However you can do this with sprintf anyway. Such
an inplementation may clash enough with 'existing usage' to make it advisable
to give the function a name other than itoa(). Something that is occasionally
useful is a function that will fill a field within a longer string i.e.
not write a null character terminator. A new function might reasonably do
that instead of duplicating existing sprintf functionality.

R. D. Davis

unread,
May 18, 1996, 3:00:00 AM5/18/96
to

In article <1996Apr12.121207@topaz>, <nad...@topaz.cqu.edu.au> wrote:
>Hi,

>
>Does anyone have or know of where I may obtain a itoa()
>integer to string function in C/C++; my Linux box
>doesn't have one and I could use it right now.

Here's one:

/*-------------------------------------------------------------------------*
* *
* Hello, hooray, let the show begin... It is FUNtime! *
* Obfuscation level: 2.5 (disregard this; the bogosity meter is pegging) *
* Obfuscated by R.D. Davis as as a part of the SACS Project from *
* PERQ Software, a div. of Transpower Industries, Inc. *
* July 22, 1994 *
* *
* Copyright (C) 1994 Robert D. Davis *
* *
* *
* *
* Once upon a midnight dreary, *
* While I hacked so nice and cheery, *
* There came a beep from number four, *
* Stranger that I'd heard before. *
* Quothe the zombie: "bats galore!" *
* *
* R.D.D. *
* */
/*???????*/house_of_usher(the_raven,nevermore)int the_raven;char nevermore[];
{int milkman,/*Is he really the eggman? Are you?*/cavegirl;/*=-_-_-_-_-_=*/
/*?*/if((cavegirl=the_raven)<0)the_raven=-the_raven;milkman=0;do{/*!@!@!@!*/
nevermore[milkman++]=the_raven%10+'0';/*^^^^^^^^*/}while((the_raven/=10)>0);
if(cavegirl<0)nevermore[milkman++]='-';nevermore[milkman]='\0';/***6L6GC***/
/*hehehe*/boojum(nevermore);}boojum(honeydew_mellon)char honeydew_mellon[];{/*
char cantaloupe;double scoop, rocky, road*//**/int cantaloupe,snark,walrus;
for(snark=0,walrus=strlen(honeydew_mellon)-1;snark<walrus;snark++,walrus--) {
cantaloupe=honeydew_mellon[snark];/*&*&*&*&*&*&*&*&*&*-________-_-_-_-_-_-_*/
/*<(=-=-=-=-=-=*/honeydew_mellon[snark]=honeydew_mellon[walrus];/*0123456789*/
/*=_=_=_=_-=-=-=-=-_-_-_-_=<><><><>()()()*/honeydew_mellon[walrus]=cantaloupe
;}}
/*------------------------------------------------------------------------*/

Well... you asked for it. :-)

--
R. D. Davis * http://www.access.digex.net/~rdd * Computer Preservationist

PERQ Logic Systems & Unconventional Computer Consulting
divisions of Transpower Industries, Inc. +1 410 744-4900

Watcher

unread,
May 19, 1996, 3:00:00 AM5/19/96
to

R. D. Davis wrote:
>
> In article <1996Apr12.121207@topaz>, <nad...@topaz.cqu.edu.au> wrote:
> >Hi,
> >
> >Does anyone have or know of where I may obtain a itoa()
> >integer to string function in C/C++; my Linux box
> >doesn't have one and I could use it right now.
>
> Here's one:
>

I think sprintf() in stdio.h can do the job which itoa() can do.

--Watcher

Brian Leach

unread,
May 20, 1996, 3:00:00 AM5/20/96
to nad...@topaz.cqu.edu.au

>
> In article <1996Apr12.121207@topaz>, <nad...@topaz.cqu.edu.au> wrote:
> >Hi,
> >
> >Does anyone have or know of where I may obtain a itoa()
> >integer to string function in C/C++; my Linux box
> >doesn't have one and I could use it right now.
>
> Here's one:
>
>
[snip]

Check out strstream. It is used almost identically to iostreams,
except you must call a 'freeze' function before reading back from
it.

-Brian :-)

Pierre Monestie

unread,
May 22, 1996, 3:00:00 AM5/22/96
to

Watcher wrote:

>
> R. D. Davis wrote:
> >
> > In article <1996Apr12.121207@topaz>, <nad...@topaz.cqu.edu.au> wrote:
> > >Hi,
> > >
> > >Does anyone have or know of where I may obtain a itoa()
> > >integer to string function in C/C++; my Linux box
> > >doesn't have one and I could use it right now.


Hi,
Here's one from the K&R

void itoa(int n,char *s)
/*Convertir entier en chaine.
E:n l'entier
S:s la chaine*/

{
int i,j,sign;
char c;
if ((sign=n)<0) n = -n;
i=0;
do {
s[i++]=n % 10 + '0';
}while ((n /=10)>0);
if (sign<0) s[i++]='-';
s[i]='\0';
for (i=0,j=strlen(s)-1;i<j;i++,j--){
c=s[i];s[i]=s[j];s[j]=c;
}
}

Andrew Gierth

unread,
May 22, 1996, 3:00:00 AM5/22/96
to

In <31A2CE...@toulouse.inra.fr>,
Pierre Monestie <mone...@toulouse.inra.fr> writes:
>>[request for itoa() fn]

>
>Hi,
>Here's one from the K&R
>
>void itoa(int n,char *s)
>/*Convertir entier en chaine.
>E:n l'entier
>S:s la chaine*/
>
>{
> int i,j,sign;
> char c;
> if ((sign=n)<0) n = -n;
> i=0;
> do {
> s[i++]=n % 10 + '0';
> }while ((n /=10)>0);
> if (sign<0) s[i++]='-';
> s[i]='\0';
> for (i=0,j=strlen(s)-1;i<j;i++,j--){
> c=s[i];s[i]=s[j];s[j]=c;
> }
>}

Well! If that really was in K&R, then that just goes to show that even
the Great Ones[tm] make mistakes...

Try itoa(INT_MIN,buf) and see what I mean. Tricky, huh?

-- Andrew (and...@microlise.co.uk)

"Usenet is like a herd of performing elephants with diarrhea; massive,
difficult to redirect, awe-inspiring, entertaining, and a source of
mind-boggling amounts of excrement when you least expect it."


Pierre Monestie

unread,
May 24, 1996, 3:00:00 AM5/24/96
to

Andrew Gierth wrote:
>
> In <31A2CE...@toulouse.inra.fr>,
> Pierre Monestie <mone...@toulouse.inra.fr> writes:
> >>[request for itoa() fn]
> >
> >Hi,
> >Here's one from the K&R
> >
> >void itoa(int n,char *s)
> >/*Convertir entier en chaine.
> >E:n l'entier

> Well! If that really was in K&R, then that just goes to show that even


> the Great Ones[tm] make mistakes...
>
> Try itoa(INT_MIN,buf) and see what I mean. Tricky, huh?
>
> -- Andrew (and...@microlise.co.uk)
>
> "Usenet is like a herd of performing elephants with diarrhea; massive,
> difficult to redirect, awe-inspiring, entertaining, and a source of
> mind-boggling amounts of excrement when you least expect it."


Ok,
Here is my prog
#define INT_MIN 46789


void itoa(int n,char *s)
/*Convertir entier en chaine.
E:n l'entier
S:s la chaine*/

{
int i,j,sign;
char c;
if ((sign=n)<0) n = -n;
i=0;
do {
s[i++]=n % 10 + '0';
}while ((n /=10)>0);
if (sign<0) s[i++]='-';
s[i]='\0';
for (i=0,j=strlen(s)-1;i<j;i++,j--){
c=s[i];s[i]=s[j];s[j]=c;
}
}

void main()
{
int int_min=12334;
char s[10];
itoa(INT_MIN,s);
printf("\n%s",s);
itoa(int_min,s);
printf("\n%s",s);
}


Here is the result
46789
12334
What's the problem???

Andrew Gierth

unread,
May 24, 1996, 3:00:00 AM5/24/96
to

In <31A5C6...@toulouse.inra.fr>, Pierre Monestie <mone...@toulouse.inra.fr> writes:

>Andrew Gierth wrote:
>>
>> Try itoa(INT_MIN,buf) and see what I mean. Tricky, huh?
>
>Ok,
>Here is my prog
>#define INT_MIN 46789
^^^^^- you must have very funny-looking ints!
Replace the above line with:
#include <limits.h>

and see what I mean.

-- Andrew (and...@microlise.co.uk)

Lawrence Kirby

unread,
May 24, 1996, 3:00:00 AM5/24/96
to

In article <4o06ds$7...@microl4.microlise.UUCP>
and...@microlise.co.uk "Andrew Gierth" writes:

>In <31A2CE...@toulouse.inra.fr>,


> Pierre Monestie <mone...@toulouse.inra.fr> writes:
>>>[request for itoa() fn]
>>
>>Hi,
>>Here's one from the K&R
>>
>>void itoa(int n,char *s)
>>/*Convertir entier en chaine.
>>E:n l'entier

>>S:s la chaine*/
>>
>>{
>> int i,j,sign;
>> char c;
>> if ((sign=n)<0) n = -n;
>> i=0;
>> do {
>> s[i++]=n % 10 + '0';
>> }while ((n /=10)>0);
>> if (sign<0) s[i++]='-';
>> s[i]='\0';
>> for (i=0,j=strlen(s)-1;i<j;i++,j--){
>> c=s[i];s[i]=s[j];s[j]=c;
>> }
>>}
>

>Well! If that really was in K&R, then that just goes to show that even
>the Great Ones[tm] make mistakes...

It was a deliberate error. The exercise following the code asks the reader
to identify the problem and correct it.

James Raynard

unread,
May 24, 1996, 3:00:00 AM5/24/96
to

In article <31A5C6...@toulouse.inra.fr>,

Pierre Monestie <mone...@toulouse.inra.fr> wrote:
>Andrew Gierth wrote:

>> Try itoa(INT_MIN,buf) and see what I mean. Tricky, huh?
>
>Ok,
>Here is my prog
>#define INT_MIN 46789

INT_MIN is a property of the implementation, defined in limits.h, not a
number to be supplied by the user. It represents the minimum number that
can be represented in an int. On many systems, the way this is implemented
will cause n to overflow in itoa(), which I think is the point that was
being made.

On my system, limits.h says

#define INT_MAX 2147483647 /* max value for an int */
#define INT_MIN (-2147483647-1) /* min value for an int */

The reason for this is given in a comment as follows:-

"The subtraction for INT_MIN and LONG_MIN is so the value is not unsigned;
2147483648 is an unsigned int for 32-bit two's complement ANSI compilers
(section 3.1.3.2)."

Now, suppose we call itoa() with INT_MIN as the integer argument. When we
reach the line

if ((sign=n)<0) n = -n;

this will result in n being set equal to -(-2147483647-1), which is
2147483648, ie greater than the maximum value the implementation can store
in an int. Hence n will overflow.

Hope this helps.

--
James Raynard, Edinburgh, Scotland
jray...@dial.pipex.com
ja...@jraynard.demon.co.uk

Andrew Gierth

unread,
May 25, 1996, 3:00:00 AM5/25/96
to

In <832977...@genesis.demon.co.uk>, Lawrence Kirby <fr...@genesis.demon.co.uk> writes:
>In article <4o06ds$7...@microl4.microlise.UUCP>
> and...@microlise.co.uk "Andrew Gierth" writes:
>>Well! If that really was in K&R, then that just goes to show that even
>>the Great Ones[tm] make mistakes...
>
>It was a deliberate error. The exercise following the code asks the reader
>to identify the problem and correct it.

Aha. I sit corrected. (I would stand corrected, but I'm too tired.)

[been - what - 9 years? since I last had my mitts on a copy of the
original K&R - my memory is good, but not *that* good...]

Anders Reed Mohn

unread,
May 25, 1996, 3:00:00 AM5/25/96
to

James Raynard wrote:
>
> In article <31A5C6...@toulouse.inra.fr>,
> Pierre Monestie <mone...@toulouse.inra.fr> wrote:
> >Andrew Gierth wrote:
>
> >> Try itoa(INT_MIN,buf) and see what I mean. Tricky, huh?
> >
> >Ok,
> >Here is my prog
> >#define INT_MIN 46789
>
> INT_MIN is a property of the implementation, defined in limits.h, not a
> number to be supplied by the user. It represents the minimum number that
> can be represented in an int. On many systems, the way this is implemented
> will cause n to overflow in itoa(), which I think is the point that was
> being made.
>
> On my system, limits.h says
>
> #define INT_MAX 2147483647 /* max value for an int */
> #define INT_MIN (-2147483647-1) /* min value for an int */


Now, I'm not very old to unix programming, so this might be a stupid question...

My college is running Solaris 2.4(?) and in limits.h all the MIN and MAX values
are defined.

Then there are float.h, values.h and a sys/types.h that define their own min/max
constants for all of this. The float.h and limits.h define equal constants
(that is INT_MIN/INT_MAX/xxx_MAX ... ), but values.h has constants named MAXINT, MAXDOUBLE,
MAXxxx etc ..

What are their different uses? I cannot make it out from reading the comments,
and I have got no documentation.

(Before you comp.lang.c folks flame me: I _did_ post this in comp.unix.programmer
as well. :) )

Anders.
================================================================================
Anders Reed Mohn, 3DT 95/96 |
Institute of Computer Science| an...@grm.hia.no
Agder College, | Ander...@ban.aid.no
N-4890 GRIMSTAD |
NORWAY | http://www.grm.hia.no/~andmo/

James Raynard

unread,
May 25, 1996, 3:00:00 AM5/25/96
to

In article <31A6D5...@grm.hia.no>,

Anders Reed Mohn <an...@grm.hia.no> wrote:
>
>My college is running Solaris 2.4(?) and in limits.h all the MIN and MAX values
>are defined.
>
>Then there are float.h, values.h and a sys/types.h that define their own min/max
>constants for all of this. The float.h and limits.h define equal constants
>(that is INT_MIN/INT_MAX/xxx_MAX ... ), but values.h has constants named MAXINT, MAXDOUBLE,
>MAXxxx etc ..
>
>What are their different uses? I cannot make it out from reading the comments,
>and I have got no documentation.

limits.h and float.h are standard C headers and specify various
constants related to integral types and floating-point arithmetic
respectively.

values.h (on my system at least) has a comment which says it's part of
the GNU C++ Library.

However, it also says (long line broken to fit in xterm)

#if __GNUC__
#warning "this file includes <values.h> which is obsoleted, use \
<limits.h> or <float.h> instead"
#endif

so presumably it shouldn't be used in new code.

Finally, sys/types.h declares various data types and constants which
are not part of standard C, but are useful for other purposes; eg
types which are required by POSIX, types which contain a known number
of bits, machine-dependent parameters like the clock-tick frequency
and so on.

Lawrence Kirby

unread,
May 26, 1996, 3:00:00 AM5/26/96
to

In article <4o5ohm$c...@microl4.microlise.UUCP>
and...@microlise.co.uk "Andrew Gierth" writes:

>In <832977...@genesis.demon.co.uk>, Lawrence Kirby
> <fr...@genesis.demon.co.uk> writes:
>>In article <4o06ds$7...@microl4.microlise.UUCP>
>> and...@microlise.co.uk "Andrew Gierth" writes:
>>>Well! If that really was in K&R, then that just goes to show that even
>>>the Great Ones[tm] make mistakes...
>>
>>It was a deliberate error. The exercise following the code asks the reader
>>to identify the problem and correct it.
>
>Aha. I sit corrected. (I would stand corrected, but I'm too tired.)
>
>[been - what - 9 years? since I last had my mitts on a copy of the
> original K&R - my memory is good, but not *that* good...]

That code came from K&R2 (it included a prototype).

Andrew Gierth

unread,
May 26, 1996, 3:00:00 AM5/26/96
to

In <833071...@genesis.demon.co.uk>,
Lawrence Kirby <fr...@genesis.demon.co.uk> writes:
>In article <4o5ohm$c...@microl4.microlise.UUCP>
> and...@microlise.co.uk "Andrew Gierth" writes:
>>[been - what - 9 years? since I last had my mitts on a copy of the
>> original K&R - my memory is good, but not *that* good...]
>
>That code came from K&R2 (it included a prototype).

Even less likely then that I would remember it - I have never read
K&R2 at all.

Interestingly enough, I think that the obfuscated version that
someone posted earlier has the same bug... not surprising really
since it's a fairly obvious one to make.

I have a minor quibble with the approach of generating the string
backwards and then reversing it in place; it seems to me to be much
preferable to generate the string in a temporary buffer and just use
strcpy() afterwards. I posted my version (which had a slightly different
interface) to c.u.p when this thread last surfaced there about a month
ago.

Lawrence Kirby

unread,
May 26, 1996, 3:00:00 AM5/26/96
to

In article <4o9oi8$f...@microl4.microlise.UUCP>
and...@microlise.co.uk "Andrew Gierth" writes:

>I have a minor quibble with the approach of generating the string
>backwards and then reversing it in place; it seems to me to be much
>preferable to generate the string in a temporary buffer and just use
>strcpy() afterwards. I posted my version (which had a slightly different
>interface) to c.u.p when this thread last surfaced there about a month
>ago.

I guess this is the danger of using a tutorial such as K&R as a reference
manual. At that point strcpy had not been introduced. The examples are there
to demonstrate a point, not necessarily to show the best
way of doing something. The actual code in K&R2 doesn't include a reverse
loop, rather it calls a reverse function that had been developed earlier.

James Raynard

unread,
May 31, 1996, 3:00:00 AM5/31/96
to

In article <TANMOY.96M...@qcd.lanl.gov>,
Tanmoy Bhattacharya <tan...@qcd.lanl.gov> wrote:
>In article <4o5898$f...@jraynard.demon.co.uk>
>ja...@jraynard.demon.co.uk (James Raynard) writes:
><snip>
>JR: "The subtraction for INT_MIN and LONG_MIN is so the value is not unsigned;
>JR: 2147483648 is an unsigned int for 32-bit two's complement ANSI compilers
>JR: (section 3.1.3.2)."
[snip]

>Thus 2147483648 cannot be an unsigned int: if long is also 32-bit, it
>is an unsigned long int, otherwise it is long.

Hmm. As was obvious from the snipped context, I was actually quoting
from a comment in limits.h on my system. The comment in full is:-

/*
* According to ANSI (section 2.2.4.2), the values below must be usable by
* #if preprocessing directives. Additionally, the expression must have the
* same type as would an expression that is an object of the corresponding
* type converted according to the integral promotions. The subtraction for
* INT_MIN and LONG_MIN is so the value is not unsigned; 2147483648 is an
* unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
* These numbers work for pcc as well. The UINT_MAX and ULONG_MAX values
* are written as hex so that GCC will be quiet about large integer constants.
*/

followed a little later by

#define INT_MAX 2147483647 /* max value for an int */
#define INT_MIN (-2147483647-1) /* min value for an int */

I agree with your reasoning that the integer constant 2147483648 must
be either an unsigned long or a long, all other things being equal;
however, the above seems to imply that the rules of integral promotion
over-ride this in the case of certain values in limits.h. Is this
true?

--
James Raynard, Edinburgh, Scotland

jray...@freebsd.org
jray...@dial.pipex.com
ja...@jraynard.demon.co.uk

Lawrence Kirby

unread,
Jun 1, 1996, 3:00:00 AM6/1/96
to

In article <4onvkh$3...@jraynard.demon.co.uk>
ja...@jraynard.demon.co.uk "James Raynard" writes:

>In article <TANMOY.96M...@qcd.lanl.gov>,
>Tanmoy Bhattacharya <tan...@qcd.lanl.gov> wrote:
>>In article <4o5898$f...@jraynard.demon.co.uk>
>>ja...@jraynard.demon.co.uk (James Raynard) writes:
>><snip>
>>JR: "The subtraction for INT_MIN and LONG_MIN is so the value is not unsigned;
>>JR: 2147483648 is an unsigned int for 32-bit two's complement ANSI compilers
>>JR: (section 3.1.3.2)."
>[snip]
>
>>Thus 2147483648 cannot be an unsigned int: if long is also 32-bit, it
>>is an unsigned long int, otherwise it is long.
>
>Hmm. As was obvious from the snipped context, I was actually quoting
>from a comment in limits.h on my system. The comment in full is:-
>
>/*
> * According to ANSI (section 2.2.4.2), the values below must be usable by
> * #if preprocessing directives. Additionally, the expression must have the
> * same type as would an expression that is an object of the corresponding
> * type converted according to the integral promotions. The subtraction for
> * INT_MIN and LONG_MIN is so the value is not unsigned; 2147483648 is an
> * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).

That is what is not true. With INT_MAX == 2147483647 It must be either long
(where LONG_MAX >= 2147483648) or unsigned long, it can never be
unsigned int. Nor can the integral promotions convert a signed type into an
unsigned type.

> * These numbers work for pcc as well. The UINT_MAX and ULONG_MAX values
> * are written as hex so that GCC will be quiet about large integer constants.
> */
>
>followed a little later by
>
>#define INT_MAX 2147483647 /* max value for an int */
>#define INT_MIN (-2147483647-1) /* min value for an int */
>
>I agree with your reasoning that the integer constant 2147483648 must
>be either an unsigned long or a long, all other things being equal;

If long is 32 bit then it must have type unsigned long. If int is more than
32 bits wide (with no holes) it would have type int.

>however, the above seems to imply that the rules of integral promotion
>over-ride this in the case of certain values in limits.h. Is this
>true?

There is nothing overriding here. The constants 2147483647 and 1 both
have type int on a system where INT_MAX is 2147483647. Therefore the
expression (-2147483647-1) has type int. As noted earlier 2147483648
has type long or unsigned long and (-2147483648) would have that same type.

James Raynard

unread,
Jun 1, 1996, 3:00:00 AM6/1/96
to

[NB comp.unix.programmer removed from followups]

In article <833630...@genesis.demon.co.uk>,


Lawrence Kirby <fr...@genesis.demon.co.uk> wrote:
>In article <4onvkh$3...@jraynard.demon.co.uk>
> ja...@jraynard.demon.co.uk "James Raynard" writes:
>
>>/*
>> * According to ANSI (section 2.2.4.2), the values below must be usable by
>> * #if preprocessing directives. Additionally, the expression must have the
>> * same type as would an expression that is an object of the corresponding
>> * type converted according to the integral promotions. The subtraction for
>> * INT_MIN and LONG_MIN is so the value is not unsigned; 2147483648 is an
>> * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
>
>That is what is not true. With INT_MAX == 2147483647 It must be either long
>(where LONG_MAX >= 2147483648) or unsigned long, it can never be
>unsigned int.

OK, I think I've got it now. (I understood the argument about the type
of an integral constant, but the reference to integral promotions
somehow managed to confuse me into thinking that the integral constant
rules didn't apply here).

If 2147483648 is an unsigned type, unary negation of it will give
another unsigned type; if it's a long, then unary negation will not
give an int either. (If it's an int, then the later definition of
INT_MAX as 2147483647 is false). Hence -2147483648 can never be an int
unless 2147483648 is.

Is this right?
--
James Raynard, Edinburgh, Scotland | http://freefall.freebsd.org/~jraynard/
ja...@jraynard.demon.co.uk | jray...@freebsd.org


Lawrence Kirby

unread,
Jun 2, 1996, 3:00:00 AM6/2/96
to

In article <4oqhi2$3...@jraynard.demon.co.uk>
ja...@jraynard.demon.co.uk "James Raynard" writes:

>If 2147483648 is an unsigned type, unary negation of it will give
>another unsigned type; if it's a long, then unary negation will not
>give an int either.

Indeed, it will give specifically a long result, or you might get undefined
behaviour from -LONG_MIN

(If it's an int, then the later definition of
>INT_MAX as 2147483647 is false). Hence -2147483648 can never be an int
>unless 2147483648 is.
>
>Is this right?

Correct. Additionally -2147483648 can *never* be an unsigned int. The
integral promotions only have an effect on char and short types which
are promoted to int or unsigned int (although you can only get an
unsigned int where the source type also has an unsigned representation).
Unadorned integer constants such as 1 or 2147483648 can't have a type shorter
than int so their types can never be affected by integral promotions.

0 new messages