A byte can be greater than 8 bits?

P

Philip Potter

jacob said:
Philip Potter wrote:

[snip]

The fact that Philippe could not bring a single example
means probably that there isn't any machines where
all those terrible conditions apply!

I'm flattered that you think so! But my knowledge of particular quirks
of different C implementations is much more restricted than you think. I
have only coded for three implementations: windows, linux, and
microblaze. I don't know the ins-and-outs of these implementations, for
reasons I've already given.

I'm quite certain that others, if they wanted, could provide details of
some implementations with some of the requested features.

Besides, I did provide a single example:
 
P

Philip Potter

Richard said:
No. It is there to make the point that it really is true. I never asked
for a comprehensive list. Just some examples.

"Look, if you do it the proper way wou wont get in a jam like you would
if you did it that way and your code moves to platform X".

In that case, I agree with the principles of your idea. But I can't
provide any examples because I'm quite ignorant of quirks of various C
implementations.
 
R

Richard

Philip Potter said:
jacob said:
Philip Potter wrote:

[snip]

The fact that Philippe could not bring a single example
means probably that there isn't any machines where
all those terrible conditions apply!

I'm flattered that you think so! But my knowledge of particular quirks
of different C implementations is much more restricted than you
think. I have only coded for three implementations: windows, linux,
and microblaze. I don't know the ins-and-outs of these
implementations, for reasons I've already given.

I'm quite certain that others, if they wanted, could provide details
of some implementations with some of the requested features.

Besides, I did provide a single example:
DSPs are a common example here.

No, you didn't. You mentioned a range of HW where it may or may not be
true :)
 
E

Eric Sosman

jacob navia wrote On 10/01/07 09:42,:
Anyway, that relies still in that all bits not dropping
of the left side are all 1. And that did not change with this minor
cosmetic change!

6.5.7p4 defines the value of the result of `-1u << n'
once UINT_MAX and n are known (and if n is in range).
6.2.6.2p4 specifies that this value is represented by n
bits zero and the rest one. That is, the fixed code relies
on the guarantees of the Standard and does not rely on the
representation of `-1'.

6.5.7p4 also says that `-1 << n' gives undefined behavior.

The difference between undefined and defined seems to me
more than "minor" or "cosmetic."
 
P

Philip Potter

Charlie said:
Philip Potter said:
Richard wrote:
2: Integer types other than unsigned char may contain padding bits, so
stay away from memcmp(arr1,arr2,sizeof arr1).
C) Places where the padding bits are not concistently set between 2
arrays of the same types.
That is user-program dependent. Any system with padding bits can have them
set by the user program:
int main(void) {
unsigned int arr1[2], arr2[2];
arr1[0] = arr1[1] = (unsigned int) -1;
memset(arr2,2*sizeof(unsigned int),1,(unsigned char)-1);
/* At this point, arr1's values equal arr2's values but
the padding bits may differ. */
}

No, nasal demons flew out of my nose... because it matters more to pass
arguments to memset in correct numbers and order which the compiler would
have hinted at had you included <string.h>.

I suggest you get a better quality implementation which provides a
no-nasal-demon guarantee then.

I'll leave correcting my code as an exercise to the reader.
 
R

Richard Heathfield

Philip Potter said:

[...] Null pointers can always be set by:
foo *x = (foo *)0;
(I'm not sure if the cast is necessary)

(No, it isn't.)
even if the null pointer representation is not all-bits-zero.

Yes, even if it means the compiler doing some magic to make it all work.
I personally don't know of any non-all-bits-zero null pointer systems,

Several such machines are mentioned in the FAQ.
I can't think why you'd want to [store a function pointer in a void *].

It's not all that unusual a thing to want to do, actually, although in
practice there's always a way around it if you want it badly enough.

As for whether systems exist that lose information when copying a function
pointer value into a void *, the answer is yes, and I've got one right
here.
 
P

Philip Potter

Richard said:
Er, I was. Here. From the people who keep telling us about them all.

Was my answer not good enough for you? It sounded to me that you had a
benevolent quest to convince people that their assumptions about the
implementation were not necessarily correct. Surely you can put some
effort into finding some? I've already given you a hint for CHAR_BIT != 8.

Meanwhile, I won't make these assumptions, and I won't have to rely on
the implementations I use to comply with these assumptions.
 
K

Kenneth Brody

Philip said:
Richard wrote: [...]
No. I think it's important to show that these systems really
exist. Otherwise a lot of people will think it's all a lot of hot
air. It does no harm to demonstrate WHERE the standard benefits the
programmer. Not some airy fairy "there might be a system with a 13 bit
char" for example.

But again, if you don't know how things are done on systems, you will be
protected from it. I know that NULL is not guaranteed to be
all-bits-zero, and I don't know where it is and where it isn't. I'm not
even sure whether or not NULL is all-bits-zero on x86, and I'm happy to
stay that way.

It's good to have a couple of examples of why certain common assumptions
shouldn't be relied on, but compiling a comprehensive list is asking for
people to rely on that list instead.

A "comprehensive list" also runs into the issue of finding "real
world" examples for all such things. Suppose, for example, that
you came up with CHAR_BITS != 8, NULL not all-bits-zero, and a
whole bunch of others, but couldn't find a system where int's
have padding bits which may be different between two ints of the
same value. Might that add to the impression that that particular
"rule" could be safely ignored?

(That's not to say that I don't have memsets on structs with
pointers in them, to set the pointers to NULL. But, I am aware
of the situation, and the application already has a bunch of
system-dependent code in it, so this particular issue is not of
concern -- for this application.)

[...]
Give me an example of code which relies on -1 being all-bits-one.

Toggling bits by xor-ing with -1.

I used to work on a platform where function pointers were 32 bits
and data pointers were 16 bits. You can't store a generic array
of function pointers in an array of void pointers.
Why is that question relevant if noone tries to do it? I don't see you
asking for a list of platforms where NULL is 0xdeadbeef, because no code
depends on that.

There's a world of difference between assuming NULL is 0xdeadbeef
and assuming NULL is all-bits-zero. For latter is often done in
code which memsets structs to zero.


--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
R

Richard

Philip Potter said:
Was my answer not good enough for you? It sounded to me that you had a
benevolent quest to convince people that their assumptions about the
implementation were not necessarily correct. Surely you can put some
effort into finding some? I've already given you a hint for CHAR_BIT
!= 8.

Are you joking? I asked for some examples of systems. Not vague "maybe
these". So, no, to be honest your "I think there are some DSPs" is not a
good enough example :-; Sorry. Your example is no more helpful than the
"On some systems a byte is more than 8 bits" type statements. Not
helpful to someone new who might like to see a concrete example. Maybe I
was not clear enough in which case I apologise. But it seems you don't
have any experience of any such platforms - so be it.

As for putting some "effort" in - I am. I am asking *here* where there
are a plethora of people who know a lot about such systems. I am hoping
they will give some examples of where a byte is more than 8 bits or
CHAR_BITS is more than 8. And it is a benevolent quest. I want to see
these systems and look at their specs too. It would be really good to
reference them whenever telling people their code is not standards
compliant.
Meanwhile, I won't make these assumptions, and I won't have to rely on
the implementations I use to comply with these assumptions.

But to do that you need to know the standard backwards. Whereas real
examples give real warnings.
 
S

santosh

Richard said:
Are you joking? I asked for some examples of systems. Not vague "maybe
these". So, no, to be honest your "I think there are some DSPs" is not a
good enough example :-; Sorry. Your example is no more helpful than the
"On some systems a byte is more than 8 bits" type statements. Not
helpful to someone new who might like to see a concrete example. Maybe I
was not clear enough in which case I apologise. But it seems you don't
have any experience of any such platforms - so be it.

Concrete examples of systems with CHAR_BITS > 8 have been mentioned before.
IIRC Jack Klein gave an example a few months ago. I also believe Keith
Thompson said that some Cray Vector machines he was familiar with had this
property.
 
P

Philip Potter

Richard said:
Are you joking? I asked for some examples of systems. Not vague "maybe
these". So, no, to be honest your "I think there are some DSPs" is not a
good enough example :-; Sorry. Your example is no more helpful than the
"On some systems a byte is more than 8 bits" type statements.

God helps those who help themselves:
http://groups.google.com/group/comp....lang.c&q=DSP+CHAR_BIT&qt_g=Search+this+group

There is your answer, already answered several times in the history of
clc. All I did was put "DSP CHAR_BIT" into a google groups search of clc.

So no, I'm not joking. I honestly thought the information I had given
you would be enough. If I was wrong, I apologise.
Not
helpful to someone new who might like to see a concrete example. Maybe I
was not clear enough in which case I apologise. But it seems you don't
have any experience of any such platforms - so be it.
>
As for putting some "effort" in - I am. I am asking *here* where there
are a plethora of people who know a lot about such systems.

....and where the question has been answered a plethora of times before.
Have a look through the archives on google groups. And the FAQ (Richard
Heathfield pointed out elsethread there are some examples of
non-all-bits-zero NULLs there).
I am hoping
they will give some examples of where a byte is more than 8 bits or
CHAR_BITS is more than 8. And it is a benevolent quest. I want to see
these systems and look at their specs too. It would be really good to
reference them whenever telling people their code is not standards
compliant.

Yes, it would be very useful. I want to stress that it is not necessary,
that is, even if there is no system where you can't fit a function
pointer into a void *, you still shouldn't do it. But it is good to have
examples of where assumptions are wrong.
But to do that you need to know the standard backwards. Whereas real
examples give real warnings.

Or heed the advice such as in the response to the OP in this thread.
 
R

Richard

santosh said:
Concrete examples of systems with CHAR_BITS > 8 have been mentioned before.
IIRC Jack Klein gave an example a few months ago. I also believe Keith
Thompson said that some Cray Vector machines he was familiar with had this
property.

Yes, so lets get them with links now so we can keep them. I would gladly
keep a list up to date.

As for Cray Vector machines, lets try and get a list of machines more
available to the common man but they would be a good start if we could
get a link to the specs.
 
R

Richard

Philip Potter said:
God helps those who help themselves:
http://groups.google.com/group/comp....lang.c&q=DSP+CHAR_BIT&qt_g=Search+this+group

There is your answer, already answered several times in the history of
clc. All I did was put "DSP CHAR_BIT" into a google groups search of
clc.

So no, I'm not joking. I honestly thought the information I had given
you would be enough. If I was wrong, I apologise.

I was asking for individuals input. Anyone can google. Here and
now. Google answers 99% of all problems asked here if you take that view.
...and where the question has been answered a plethora of times
before. Have a look through the archives on google groups. And the FAQ
(Richard Heathfield pointed out elsethread there are some examples of
non-all-bits-zero NULLs there).


Yes, it would be very useful. I want to stress that it is not
necessary, that is, even if there is no system where you can't fit a

It is necessary in the real world. People need
examples. Sorry. Otherwise it's like Pandoras box. Never look in, just
take our word ....
function pointer into a void *, you still shouldn't do it. But it is
good to have examples of where assumptions are wrong.

I'm particularly interested in this void * not being able to hide a
function pointer bit. I wonder how casting a func pointer to a void
printf works then? Or it isn't?
Or heed the advice such as in the response to the OP in this thread.

Some people need examples. I am one such. The examples I am looking to
gather in a single place are to avoid having to rely on certain posters
assertions.
 
J

jacob navia

Richard said:
Yes, so lets get them with links now so we can keep them. I would gladly
keep a list up to date.

As for Cray Vector machines, lets try and get a list of machines more
available to the common man but they would be a good start if we could
get a link to the specs.

K. Thomson said it was in a very old Cray implementation. Probably
the newer ones do not use that since ages.
 
K

Kenneth Brody

Ben said:
If you suspect it is not, why not say why?

Because is just looks "wrong". :)

To me, it looks like "take negative one as an unsigned value", even
though the real meaning is "negate the unsigned int value 1, and give
the result as an unsigned int".

In other words, as I understand it (now that I've looked into it a
little), "-1u" is really two tokens -- "-" and "1u".
It seems to me to to be perfectly well defined. The '1u' has promoted
type 'unsigned int', the '-' negates this. The result (mathematical
-1) is converted back to the promoted type (unsigned int) by
repeatedly adding (or subtracting) one more than the maximum value
representable in that type (UINT_MAX + 1).


--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

santosh said:
Concrete examples of systems with CHAR_BITS > 8 have been mentioned before.
IIRC Jack Klein gave an example a few months ago. I also believe Keith
Thompson said that some Cray Vector machines he was familiar with had this
property.

Quibble: CHAR_BIT, not CHAR_BITS.

No, the Cray vector machines I've used had CHAR_BIT==8. The C
compiler had to go to considerable lengths to make this work, since
the smallest directly hardware-addressable unit of storage is a 64-bit
word. It would have been easier, and arguably more logical, for the C
compiler to use CHAR_BIT==64, but that would have broken compatibility
with other systems with which they had to communicate. The systems in
question ran a Unix operating system (UNICOS); I think POSIX requires
CHAR_BIT=8.

The last Cray vector system I used was the T90; it was shut down in
2002. There were newer Cray vector systems, but I never used them --
but since the need for interoperability certainly wouldn't have gone
away, I'd be very surprised if they had CHAR_BIT > 8.
 
K

Keith Thompson

Richard said:
I would be very interested for posters here to list the current systems
they use which would cause problems by breaking the rules. It might be a
good edition to the FAQ for people to go out and find real systems so as
to understand better why they need to be careful: [snip]
E) Where a function pointer can not be stored in a VOID
pointer. (Regardless of style)

A small quibble: Putting C identifiers or keywords in all-caps for
emphasis is not a good idea. void is a keyword; VOID is an identifier
and could very plausibly be a macro name (for example, I've seen code
that conditionally uses ``#define VOID int'' for pre-ANSI
compatibility). This is, as the phrase "small quibble" implies, not a
big deal, and I wouldn't have bothered to mention if it I weren't also
making another point.

Attempting to convert a function pointer to void* invoked undefined
behavior. (I had thought it was a constraint violation, but a quick
check of the standard doesn't support that.) A compiler isn't even
required to compile code that attempts such a conversion, regardless
of whether it *could* meaningfully do so. I would be unsurprised to
see a C compiler that rejects a program that attempts such a
conversion.

As for a specific example, I believe IBM AS/400 has been presented
here as such a system. My vague recollection is that function
pointers are considerably larger than void*. I've never used an
AS/400 system, so I can't confirm that.

If you're not getting some of the specific examples you're asking for,
it may be partly because some of the people who know about such
example have killfiled you. Behavior has consequences.
 
?

=?iso-2022-kr?q?Harald_van_D=0E=29=26=0Fk?=

Quibble: CHAR_BIT, not CHAR_BITS.

No, the Cray vector machines I've used had CHAR_BIT==8. The C compiler
had to go to considerable lengths to make this work, since the smallest
directly hardware-addressable unit of storage is a 64-bit word. It
would have been easier, and arguably more logical, for the C compiler to
use CHAR_BIT==64, but that would have broken compatibility with other
systems with which they had to communicate. The systems in question ran
a Unix operating system (UNICOS); I think POSIX requires CHAR_BIT=8.

<OT> Before the end of 2001, it didn't. (And after that, it only did
because C99 added a pointless requirement that uint8_t contain no padding
bits.) If they defined CHAR_BIT as 8, that's most likely a very sensible
decision, but one that had little to do with POSIX.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top