Thread View: comp.std.c
9 messages
9 total messages
Started by David Wald
Sat, 24 Feb 1996 18:15
sizeof(char) ~= sizeof(float)
Author: David Wald
Date: Sat, 24 Feb 1996 18:15
Date: Sat, 24 Feb 1996 18:15
29 lines
1903 bytes
1903 bytes
During a recent recurrence of the perennial "how big is an int" discussion on comp.lang.c.moderated, I described a freestanding C implementation I'd dealt with in which, as in some other word-based implementations, sizeof(char) == sizeof(long) == sizeof(float). However, one quirk of this architecture was that not all interpretations of a memory word could see all bits. In particular, though integral types and floats each took one word, a float used 8 more bits than the integral types. When a word was used in integral operations, the lower 8 bits were invisible and harmless. Thus you could have two sections of memory which could be distinguished when viewed through float*'s but not when viewed through char*'s. Can such an implementation be ANSI-conformant? The basic argument against, presented by Tanmoy Bhattacharya, is that memory compare, and possibly memory copy functions, can't be implemented in a portable fashion if two dissimilar regions of memory can't be distinguished by comparing them char-wise. (I'm unsure about the memory copy, since I've forgotten whether the implementation actually preserved the hidden 8 bits when you copied a char.) Does this violate a constraint of the standard? At Tanmoy's suggestion, I'm putting the question before the collected wisdom comp.std.c. -David -- ============================================================================ David Wald http://theory.lcs.mit.edu/~wald/ wald@theory.lcs.mit.edu ============================================================================
Re: sizeof(char) ~= sizeof(float)
Author: Norman Diamond
Date: Mon, 26 Feb 1996 01:46
Date: Mon, 26 Feb 1996 01:46
50 lines
3348 bytes
3348 bytes
In article <WALD.96Feb24131532@woodpecker.lcs.mit.edu>, wald@theory.lcs.mit.edu (David Wald) writes: >During a recent recurrence of the perennial "how big is an int" >discussion on comp.lang.c.moderated, I described a freestanding C >implementation I'd dealt with in which, as in some other word-based >implementations, sizeof(char) == sizeof(long) == sizeof(float). >However, one quirk of this architecture was that not all >interpretations of a memory word could see all bits. In particular, >though integral types and floats each took one word, a float used 8 >more bits than the integral types. When a word was used in integral >operations, the lower 8 bits were invisible and harmless. Thus you >could have two sections of memory which could be distinguished when >viewed through float*'s but not when viewed through char*'s. >Can such an implementation be ANSI-conformant? At present, I think it can. As written, the standard does not say whether types char, signed char, and unsigned char are required to use all bits of the storage they occupy in determining the values they represent. Bits not used are now called "holes" (which is not what they were called by the base document K&R-I). Rumor has it that Technical Corrigendum 2 will change the standard so that unsigned char cannot have any holes. Signed char will still be allowed to have holes, and char will still have to behave either as unsigned char (no holes) or as signed char (identical holes). >The basic argument against, presented by Tanmoy Bhattacharya, is that >memory compare, and possibly memory copy functions, can't be implemented >in a portable fashion if two dissimilar regions of memory can't be >distinguished by comparing them char-wise. Is that really what he said? I'm sure Mr. Bhattacharya knows many parts of the standard which cannot be implemented in a portable fashion. Every implementation has to provide some degree of portability to some kinds of programs -- that is what the standard requires -- but an implementation itself does not port so easily. So, what is one more minor grunge? >(I'm unsure about the memory copy, since I've forgotten whether the >implementation actually preserved the hidden 8 bits when you copied a char.) If you assign one char to another using an assignment operator, it doesn't have to do so. (Except of course that after TC2, if you use unsigned chars, then there can't be hidden bits any more.) If you use memcpy or possibly if you play tricks with union types, you can force it to copy all the bits. -- << 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
Re: sizeof(char) ~= sizeof(float)
Author: Tanmoy Bhattacharya
Date: Mon, 26 Feb 1996 03:35
Date: Mon, 26 Feb 1996 03:35
71 lines
3880 bytes
3880 bytes
In article <4gr3d1$dca@usenet.pa.dec.com> diamond@tbj.dec.com (Norman Diamond) writes: <snip> ND: Rumor has it that Technical Corrigendum 2 will change the standard so that ND: unsigned char cannot have any holes. Signed char will still be allowed to ND: have holes, and char will still have to behave either as unsigned char (no ND: holes) or as signed char (identical holes). What happens to the requirement that positive signed integral values have to have the same representation as the corresponding unsigned integral value? Coupled with the requirement of pure binary representation (I am not sure what `pure binary' means: assuming it means that only one bit can represent the sign), it seems to say that if unsigned char can't have holes, neither can signed char unless whether a certain bit contributes to the value or not depends on the sign bit; I assume such `holes' are allowed? ND: ND: >The basic argument against, presented by Tanmoy Bhattacharya, is that ND: >memory compare, and possibly memory copy functions, can't be implemented ND: >in a portable fashion if two dissimilar regions of memory can't be ND: >distinguished by comparing them char-wise. ND: ND: Is that really what he said? I'm sure Mr. Bhattacharya knows many parts ND: of the standard which cannot be implemented in a portable fashion. Every ND: implementation has to provide some degree of portability to some kinds of ND: programs -- that is what the standard requires -- but an implementation ND: itself does not port so easily. So, what is one more minor grunge? ND: No, that was not the argument. I was assuming that the rumored TC2 interpretation will be adopted. The argument is that in float x, y; unsigned char *xx=(void*)&x, *yy=(void*)&y; copying (or comparing) sizeof(float) unsigned chars from xx to yy must manage to copy (or compare) x from y. The suggestion to post to comp.std.c was precisely because this was a rumor, and people in this group are more likely to know whether I have got the gossip right :-) <snip> ND: If you assign one char to another using an assignment operator, it doesn't ND: have to do so. (Except of course that after TC2, if you use unsigned chars, ND: then there can't be hidden bits any more.) Whether or not `char' can have holes, if there are say two representations of 0 (sign-magnitude / one's complement etc.) a copy of char can change one representation to the other. ND: ND: If you use memcpy or possibly if you play tricks with union types, you can ND: force it to copy all the bits. This was a free-standing implementation, and memcpy may be absent. (In a hosted implementation, as all read/write is done as if through getc/putc which handles unsigned char values, and binary files written out must be read back unchanged, the situation is impossible). Cheers Tanmoy -- tanmoy@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tanmoy@lanl.gov"(1.218=1242) Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544 Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>, <http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/ internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html> fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]
Re: sizeof(char) ~= sizeof(float)
Author: Christopher R Volpe
Date: Mon, 26 Feb 1996 15:32
Date: Mon, 26 Feb 1996 15:32
46 lines
2735 bytes
2735 bytes
David Wald wrote: > [...] > However, one quirk of this architecture was that not all > interpretations of a memory word could see all bits. In particular, > though integral types and floats each took one word, a float used 8 > more bits than the integral types. When a word was used in integral > operations, the lower 8 bits were invisible and harmless. Thus you > could have two sections of memory which could be distinguished when > viewed through float*'s but not when viewed through char*'s. > > Can such an implementation be ANSI-conformant? The basic argument > against, presented by Tanmoy Bhattacharya, is that memory compare, and > possibly memory copy functions, can't be implemented in a portable > fashion if two dissimilar regions of memory can't be distinguished by > comparing them char-wise. I don't think this is relevant. At issue here is the behavior of strictly conforming code presented to the implementation, not the ease, or even possibility, of implementing the standard library using the language of the compiler. The implementation is required to provide a memcmp function that works as described. If that requires the implementation of memcmp to compare floats instead of chars, or to use an assembler octet-compare instruction, then so be it. And it's none of your business whether or not it does that. > (I'm unsure about the memory copy, since > I've forgotten whether the implementation actually preserved the > hidden 8 bits when you copied a char.) Does this violate a constraint > of the standard? "Constraints" are imposed upon user programs, not compiler implementations. Though you probably meant "constraint" in the looser sense, not in the specific ANSI sense. In that case, the one sure-fire way to demonstrate non-conformance is to present a strictly conforming program, whose behavior will be clearly discernable by reading the Standard, that elicits improper output from the compiler in question. So, can you produce such a program? -- Chris Volpe Phone: (518) 387-7766 (Dial Comm 8*833 GE Corporate R&D Fax: (518) 387-6560 PO Box 8, Schenectady, NY 12301 Email: volpecr@crd.ge.com
Re: sizeof(char) ~= sizeof(float)
Author: Stephen Baynes
Date: Tue, 27 Feb 1996 13:09
Date: Tue, 27 Feb 1996 13:09
21 lines
1707 bytes
1707 bytes
Tanmoy Bhattacharya (tanmoy@qcd.lanl.gov) wrote: : In article <4gr3d1$dca@usenet.pa.dec.com> : diamond@tbj.dec.com (Norman Diamond) writes: <snip - copying data by using chars of different sorts vs memcpy > : This was a free-standing implementation, and memcpy may be absent. (In : a hosted implementation, as all read/write is done as if through : getc/putc which handles unsigned char values, and binary files written : out must be read back unchanged, the situation is impossible). That read/write is done by getc/putc does not imply very much about copying chars. I don't see any requirement that fwrite/fread use one putc/getc per byte(ie char) of memory. Fwrite could use one per bit writing the values 'Y' or 'N' if it wanted so long as fread will read it back again. My understanding is that the use of getc/putc means you can write a file with fwrite, copy it with getc/putc and read the copy with fread to get what you started with. -- Stephen Baynes baynes@ukpsshp1.serigate.philips.nl Philips Semiconductors Ltd Southampton My views are my own. United Kingdom
Re: sizeof(char) ~= sizeof(float)
Author: Tanmoy Bhattacharya
Date: Tue, 27 Feb 1996 18:42
Date: Tue, 27 Feb 1996 18:42
36 lines
2507 bytes
2507 bytes
In article <DnFr78.1wo@ukpsshp1.serigate.philips.nl> baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes: SB: Tanmoy Bhattacharya (tanmoy@qcd.lanl.gov) wrote: SB: : In article <4gr3d1$dca@usenet.pa.dec.com> SB: : diamond@tbj.dec.com (Norman Diamond) writes: SB: <snip - copying data by using chars of different sorts vs memcpy > SB: : This was a free-standing implementation, and memcpy may be absent. (In SB: : a hosted implementation, as all read/write is done as if through SB: : getc/putc which handles unsigned char values, and binary files written SB: : out must be read back unchanged, the situation is impossible). SB: SB: That read/write is done by getc/putc does not imply very much about copying SB: chars. I don't see any requirement that fwrite/fread use one putc/getc per SB: byte(ie char) of memory. Fwrite could use one per bit writing the values 'Y' or SB: 'N' if it wanted so long as fread will read it back again. My understanding SB: is that the use of getc/putc means you can write a file with fwrite, copy it SB: with getc/putc and read the copy with fread to get what you started with. I understood it to mean that I could take the same (void*) pointer to the data, and call putc repeatedly on the successive bytes of the data, and the resulting file is identical to doing an fwrite. I think the standard should clarify its meaning. Cheers Tanmoy -- tanmoy@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tanmoy@lanl.gov"(1.218=1242) Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544 Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>, <http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/ internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html> fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]
fread/fwrite [was Re: sizeof(char) ~= sizeof(float)]
Author: Nick Maclaren
Date: Tue, 27 Feb 1996 19:40
Date: Tue, 27 Feb 1996 19:40
30 lines
2044 bytes
2044 bytes
In article <DnFr78.1wo@ukpsshp1.serigate.philips.nl>, Stephen Baynes <baynes@ukpsshp1.serigate.philips.nl> wrote: >Tanmoy Bhattacharya (tanmoy@qcd.lanl.gov) wrote: >: In article <4gr3d1$dca@usenet.pa.dec.com> >: diamond@tbj.dec.com (Norman Diamond) writes: ><snip - copying data by using chars of different sorts vs memcpy > >: This was a free-standing implementation, and memcpy may be absent. (In >: a hosted implementation, as all read/write is done as if through >: getc/putc which handles unsigned char values, and binary files written >: out must be read back unchanged, the situation is impossible). > >That read/write is done by getc/putc does not imply very much about copying >chars. I don't see any requirement that fwrite/fread use one putc/getc per >byte(ie char) of memory. Fwrite could use one per bit writing the values 'Y' or >'N' if it wanted so long as fread will read it back again. My understanding >is that the use of getc/putc means you can write a file with fwrite, copy it >with getc/putc and read the copy with fread to get what you started with. Not quite. You must either do ALL I/O as text or ALL as binary! This isn't stated by the standard, but fread and fwrite are unimplementable if it is not true. I would prefer them to be forbidden on text files, or at least implementation defined. Nick Maclaren, University of Cambridge Computer Laboratory, New Museums Site, Pembroke Street, Cambridge CB2 3QG, England. Email: nmm1@cam.ac.uk Tel.: +44 1223 334761 Fax: +44 1223 334679
Re: sizeof(char) ~= sizeof(float)
Author: Norman Diamond
Date: Wed, 28 Feb 1996 08:07
Date: Wed, 28 Feb 1996 08:07
73 lines
4044 bytes
4044 bytes
In article <TANMOY.96Feb25203514@qcd.lanl.gov>, tanmoy@qcd.lanl.gov (Tanmoy Bhattacharya) writes:
>In article <4gr3d1$dca@usenet.pa.dec.com>
>diamond@tbj.dec.com (Norman Diamond) writes:
>>Rumor has it that Technical Corrigendum 2 will change the standard so that
>>unsigned char cannot have any holes. Signed char will still be allowed to
>>have holes, and char will still have to behave either as unsigned char (no
>>holes) or as signed char (identical holes).
>What happens to the requirement that positive signed integral values
>have to have the same representation as the corresponding unsigned
>integral value? Coupled with the requirement of pure binary
>representation [...] it seems to say that if unsigned char can't have
>holes, neither can signed char
ANSI Classic section 3.1.2.5, freshly unpacked in this month's new office,
page 24 lines 3 to 5: "The range of nonnegative values of a signed
integer type is a subrange of the corresponding unsigned integer type,
and the representation of the same value in each type is the same."
If unsigned char can hold the value 255 but signed char cannot, there is
no violation of the "subrange" requirement and there is no signed
representation to be matched. Even if unsigned char can hold the value
65535 but signed char cannot hold values 65535 or 255, no problem.
>unless whether a certain bit contributes to the value or not depends on the
>sign bit; I assume such `holes' are allowed?
I have a vague impression that this kind of hole is not allowed. A hole
is either part of the representation of the type or it is not.
>I was assuming that the rumored TC2 interpretation will be adopted.
>The argument is that in
> float x, y;
> unsigned char *xx=(void*)&x, *yy=(void*)&y;
>copying (or comparing) sizeof(float) unsigned chars from xx to yy must
>manage to copy (or compare) x from y.
Or more precisely:
float x, y;
unsigned char (*xx)[sizeof(float)]=(void*)&x,
(*yy)[sizeof(float)]=(void*)&y;
*yy = *xx;
Yes, if the rumored TC2 interpretation is adopted, I think this will
have to work.
>Whether or not `char' can have holes, if there are say two
>representations of 0 (sign-magnitude / one's complement etc.) a copy
>of char can change one representation to the other.
I think so.
[Without, or before, TC2]:
>>If you use memcpy or possibly if you play tricks with union types, you can
>>force it to copy all the bits.
>This was a free-standing implementation, and memcpy may be absent.
I think suitable union types would still work. But now I wonder, if the
programmer knows that the objects are floats, why not just assign floats?
[Regardless of TC2, I think]:
>(In a hosted implementation, as all read/write is done as if through
>getc/putc which handles unsigned char values, and binary files written
>out must be read back unchanged, the situation is impossible).
Actually there's already a problem here. If there are two representations
of 0 but all read/write is done as if through functions which convert
between int and unsigned char, it is impossible to read some stuff back
unchanged. I hope a DR was submitted about this a few years ago.
--
<< 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
Re: sizeof(char) ~= sizeof(float)
Author: Lawrence Kirby
Date: Sun, 17 Mar 1996 00:59
Date: Sun, 17 Mar 1996 00:59
52 lines
2788 bytes
2788 bytes
In article <TANMOY.96Feb27114201@qcd.lanl.gov>
tanmoy@qcd.lanl.gov "Tanmoy Bhattacharya" writes:
>In article <DnFr78.1wo@ukpsshp1.serigate.philips.nl>
>baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:
>
>SB: Tanmoy Bhattacharya (tanmoy@qcd.lanl.gov) wrote:
>SB: : In article <4gr3d1$dca@usenet.pa.dec.com>
>SB: : diamond@tbj.dec.com (Norman Diamond) writes:
>SB: <snip - copying data by using chars of different sorts vs memcpy >
>SB: : This was a free-standing implementation, and memcpy may be absent. (In
>SB: : a hosted implementation, as all read/write is done as if through
>SB: : getc/putc which handles unsigned char values, and binary files written
>SB: : out must be read back unchanged, the situation is impossible).
>SB:
>SB: That read/write is done by getc/putc does not imply very much about copying
>SB: chars. I don't see any requirement that fwrite/fread use one putc/getc per
>SB: byte(ie char) of memory. Fwrite could use one per bit writing the
>values 'Y' or
>SB: 'N' if it wanted so long as fread will read it back again. My
>understanding
>SB: is that the use of getc/putc means you can write a file with
>fwrite, copy it
>SB: with getc/putc and read the copy with fread to get what you started with.
>
>I understood it to mean that I could take the same (void*) pointer to
>the data, and call putc repeatedly on the successive bytes of the
>data, and the resulting file is identical to doing an fwrite. I think
>the standard should clarify its meaning.
OK, I'm a little late in getting round to this! :-)
This is a property that fread/fwrite really must have if they are to be
of much use. Without it you can't use them for random access reading/writing
of record because you don't know how large those records are going to
end up being in the file, even using a binary stream.
This would also bring into question whether:
fwrite(str, 1, strlen(str), fp)
has the same effect (ignoring the return values) as:
fputs(str, fp)
for valid arguments.
--
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads