🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

9 total messages Started by David Wald Sat, 24 Feb 1996 18:15
sizeof(char) ~= sizeof(float)
#4790
Author: David Wald
Date: Sat, 24 Feb 1996 18:15
29 lines
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)
#4822
Author: Norman Diamond
Date: Mon, 26 Feb 1996 01:46
50 lines
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)
#4831
Author: Tanmoy Bhattacharya
Date: Mon, 26 Feb 1996 03:35
71 lines
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)
#4828
Author: Christopher R Volpe
Date: Mon, 26 Feb 1996 15:32
46 lines
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)
#4833
Author: Stephen Baynes
Date: Tue, 27 Feb 1996 13:09
21 lines
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)
#4839
Author: Tanmoy Bhattacharya
Date: Tue, 27 Feb 1996 18:42
36 lines
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)]
#4835
Author: Nick Maclaren
Date: Tue, 27 Feb 1996 19:40
30 lines
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)
#4836
Author: Norman Diamond
Date: Wed, 28 Feb 1996 08:07
73 lines
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)
#4899
Author: Lawrence Kirby
Date: Sun, 17 Mar 1996 00:59
52 lines
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