rg@msel.unh.edu (Roger Gonzalez) (03/07/91)
the following program demonstrates this "bug":
main()
{
int i;
long j;
for (i = 0; i < 1000; i++, j = i*2)
printf("oh crud: %x %10d %x\r", i, j, i);
}
The third number printed is always zero. It corrects itself if the
second formatting string is %10ld. Is this a new ansi-ism? Will this
behavior change to what my Unix cc fingers expect if I set it to K&R?
Is it a bug? I can see them arguing that it isn't a bug, but I find
it an unpleasant nonbug at the very least.
-Roger
--
"The question of whether a computer can think is no more interesting
than the question of whether a submarine can swim" - Edsgar W. Dijkstra
rg@[msel|unhd].unh.edu | UNH Marine Systems Engineering Laboratory
r_gonzalez@unhh.bitnet | Durham, NH 03824-3525
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/07/91)
In article <1991Mar6.173733.430@unhd.unh.edu> rg@msel.unh.edu (Roger Gonzalez) writes: > int i; > long j; > for (i = 0; i < 1000; i++, j = i*2) > printf("oh crud: %x %10d %x\r", i, j, i); > The third number printed is always zero. It corrects itself if the > second formatting string is %10ld. This makes perfect sense. On a low level, printf is expecting three 2-byte arguments; you fed it a 2-byte, a 4-byte, and another 2-byte. The 4-byte always has high word 0 since j is smaller than 65536. Numbers are stored low-byte first on that machine. So the third 2-byte is 0. If anything were done differently---a noncontiguous stack, or arguments passed in registers, or a different word order, or whatever---you'd see different results with the original code. When you use %10ld, printf knows to expect a long for its second argument. > Will this > behavior change to what my Unix cc fingers expect if I set it to K&R? You mean ``to what my all-the-world's-a-VAX fingers expect.'' You have to distinguish properly between ints and longs if you want your programs to work on machines where int != long. ---Dan
henry@zoo.toronto.edu (Henry Spencer) (03/07/91)
In article <1991Mar6.173733.430@unhd.unh.edu> rg@msel.unh.edu (Roger Gonzalez) writes: >The third number printed is always zero. It corrects itself if the >second formatting string is %10ld. Is this a new ansi-ism? Will this >behavior change to what my Unix cc fingers expect if I set it to K&R? >Is it a bug? ... It is not a bug; it is correct behavior. Printing a long with %d has always been wrong, and if it worked it was because you were lucky in your choice of machine and compiler such that it accidentally came out right. -- "But this *is* the simplified version | Henry Spencer @ U of Toronto Zoology for the general public." -S. Harris | henry@zoo.toronto.edu utzoo!henry
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (03/07/91)
In article <1991Mar6.173733.430@unhd.unh.edu>, rg@msel.unh.edu (Roger Gonzalez) writes: > int i; > long j; > printf("oh crud: %x %10d %x\r", i, j, i); > Is this a new ansi-ism? Nope, that's the way it was back when 'long' became available on PDP-11s. Always use "%d", "%x" and so on for "int". (PDP-11: 2 == sizeof (int)) Always use "%ld", "%lx" and so on for "long". (PDP-11: 4 == sizeof (long)) No need to worry about "char" or "short", as they promote to "int". > Will this > behavior change to what my Unix cc fingers expect if I set it to K&R? This *IS* what UNIX cc compilers require. You are confusing "machine where sizeof (int) == sizeof (long)" with "UNIX machine". 'Tisn't so. PDP-11s & Z8000s running UNIX had the same problem for the same reason. -- The purpose of advertising is to destroy the freedom of the market.
kirste@methan.chemie.fu-berlin.de (Burkhard Kirste) (03/07/91)
rg@msel.unh.edu (Roger Gonzalez) writes: >the following program demonstrates this "bug": >main() >{ > int i; > long j; > > for (i = 0; i < 1000; i++, j = i*2) > printf("oh crud: %x %10d %x\r", i, j, i); >} > >The third number printed is always zero. It corrects itself if the >second formatting string is %10ld. Is this a new ansi-ism? Will this >behavior change to what my Unix cc fingers expect if I set it to K&R? >Is it a bug? I can see them arguing that it isn't a bug, but I find >it an unpleasant nonbug at the very least. > Under UNIX, it doesn't matter: int = long = 32 bit (usually), although you have to specify %hd for short int (16 bit). Otherwise, if int = 16 bit, long = 32 bit, you have to use %ld for long. That is simply logical, not a "bug"! -- |~| Freie Universitaet Berlin, Institut fuer Organische Chemie / \ Burkhard Kirste kirste@kristall.chemie.fu-berlin.dbp.de /FUB\ Takustrasse 3, D-1000 Berlin 33 UUCP: kirste@fub.uucp `---' Telefon: (030)838-6484 Telefax: (030)838-5163
dcurtis@crc.ac.uk (Dr. David Curtis) (03/08/91)
In article <1991Mar6.173733.430@unhd.unh.edu> rg@msel.unh.edu (Roger Gonzalez) writes: >the following program demonstrates this "bug": >main() >{ > int i; > long j; > > for (i = 0; i < 1000; i++, j = i*2) > printf("oh crud: %x %10d %x\r", i, j, i); >} > >The third number printed is always zero. It corrects itself if the >second formatting string is %10ld. Is this a new ansi-ism? Will this >behavior change to what my Unix cc fingers expect if I set it to K&R? >Is it a bug? I can see them arguing that it isn't a bug, but I find >it an unpleasant nonbug at the very least. > Of course this isn't a bug. The only way it could possibly work as you apparently intend if int and long were the same size. You seem to expect printf() to know the size of the arguments which have been put on the stack, but of course the only way for it to do this is by providing if with a (correct) format string. Dave Curtis Academic Department of Psychiatry, Janet: dc@UK.AC.UCL.SM.PSYCH Middlesex Hospital, Elsewhere: dc@PSYCH.SM.UCL.AC.UK Mortimer Street, London W1N 8AA. EARN/Bitnet: dc%PSYCH.SM.UCL@UKACRL Tel 071-636 8333 Fax 071-323 1459 Usenet: ...!mcsun!ukc!mrccrc!D.Curtis
ch@dce.ie (Charles Bryant) (03/10/91)
In article <1991Mar6.173733.430@unhd.unh.edu> rg@msel.unh.edu (Roger Gonzalez) writes: >main() >{ > int i; > long j; > > for (i = 0; i < 1000; i++, j = i*2) > printf("oh crud: %x %10d %x\r", i, j, i); >} Surely I am not the only person to notice that j is used before being set? (On the first pass only). Maybe our newsfeed is just clogged. -- Charles Bryant (ch@dce.ie) -- If you like the opinions expressed in this message, they may be available for rent - contact your local sales office. Low interest deals available.
boyd@necisa.ho.necisa.oz.au (Boyd Roberts) (03/11/91)
In article <DDTO3BF@methan.chemie.fu-berlin.de> kirste@methan.chemie.fu-berlin.de (Burkhard Kirste) writes: >Under UNIX, it doesn't matter: int = long = 32 bit (usually), >although you have to specify %hd for short int (16 bit). I can see you have vast experience on many UNIX machines. Repeat after me: long and int are not the same >Otherwise, if int = 16 bit, long = 32 bit, you have to use >%ld for long. That is simply logical, not a "bug"! No, %d for int, %ld for long. It doesn't matter how many bits are involved, the whole issue is to do with the _type_ of the arguments. Use the right format specifiers for the right types -- forget bits. Boyd Roberts boyd@necisa.ho.necisa.oz.au ``When the going gets wierd, the weird turn pro...''
mwizard@eecs.cs.pdx.edu (Craig Nelson) (03/11/91)
ch@dce.ie (Charles Bryant) writes: >In article <1991Mar6.173733.430@unhd.unh.edu> rg@msel.unh.edu (Roger Gonzalez) writes: >>main() >>{ >> int i; >> long j; >> >> for (i = 0; i < 1000; i++, j = i*2) >> printf("oh crud: %x %10d %x\r", i, j, i); >>} >Surely I am not the only person to notice that j is used before being >set? (On the first pass only). Maybe our newsfeed is just clogged. >-- >Charles Bryant (ch@dce.ie) No, you're not the only one. I wonder if he tried this instead, and then check for his 'bug': main() { int i=0;j=0; for (;i<1000;i++,j=i*2) printf("oh crud: %x %10d %x\r", i, j, i); } Also, I was always under the impression that long defaulted to an integer format (a long one). I wonder why he is trying to format it to a double format in the printf() statement ? Craig Nelson (mwizard@eecs.ee.pdx.edu)
rg@msel.unh.edu (Roger Gonzalez) (03/11/91)
My stupid trivial program that started this whole sordid thread, which has involved countless flames against me and my ancestry: >>>main() >>>{ >>> int i; >>> long j; >>> >>> for (i = 0; i < 1000; i++, j = i*2) >>> printf("oh crud: %x %10d %x\r", i, j, i); >>>} ^ I was wondering why I had to use %ld instead of %d, since I never had done so in the past. I wondered if it was an ansi-ism, and if K&R cc's were just smarter about %d and could deduce size. The correct answer as a few people pointed out, is that printf needs to know how many bytes to slurp off the stack. I had had the luck to always have used machines with sizeof(int)==sizeof(long). Also, I've always used machines with "correct" :-) byte ordering. Since I was using a PC, a machine I generally try to avoid, I forgot about Intel byte ordering. (Little-endian? Never actually had cause to use that term) So, the high bytes of 'j' get read in as the value for the last 'i' printed. Since I never went above 1000, this was always 0. On a big-endian machine with sizeof(int) != sizeof(long), the output should be (for example) a 0 20 on a PC it is a 20 0 Voila. I've been enlightened. >ch@dce.ie (Charles Bryant) correctly but pointlessly writes: > >>Surely I am not the only person to notice that j is used before being >>set? (On the first pass only). Maybe our newsfeed is just clogged. True. However, since this was supposed to be just a minimalist program to demonstrate concept, and when I was reducing the screen real estate it took to list the code, I moved a 'j = i * 2' into the 'for' without a 'j = 0'. My booboo. In article <1906@pdxgate.UUCP> mwizard@eecs.cs.pdx.edu (Craig Nelson) writes: >No, you're not the only one. I wonder if he tried this instead, and then >check for his 'bug': > >main() >{ int i=0;j=0; > > for (;i<1000;i++,j=i*2) > printf("oh crud: %x %10d %x\r", i, j, i); > >} > >Also, I was always under the impression that long defaulted to an >integer format (a long one). I wonder why he is trying to format it >to a double format in the printf() statement ? > >Craig Nelson (mwizard@eecs.ee.pdx.edu) Huh? I think you're not only missing the point, but just plain -wrong- to boot. AT ANY RATE... Thank you, if you were polite and helpful.. Eat cow dung and die slowly, if you flamed me.. You wouldn't believe the number of postings that said, in effect, "hey stupid - you should use %ld, not %d!" I knew that. Reread the posting; I wrote "it works correctly with %10ld." I asked WHY was this compiler MAKING me use %ld, when I had gotten away with %d in the past. There's a difference. What are the morals of this story? - using the same types of machines all your life can be hazardous to your programming style - if you want wide readership, post about possible bugs in popular programs - the less people understand the WHY's, the more emphatically they expound on their learned-by-rote rules, as if it were a religious chant - there are just as many assholes on this group as any other group Cheers, Roger -- "The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsgar W. Dijkstra rg@[msel|unhd].unh.edu | UNH Marine Systems Engineering Laboratory r_gonzalez@unhh.bitnet | Durham, NH 03824-3525