FAQ-Question

K

Keith Thompson

Frederick Gotham said:
The Standard specifies that "all bits zero" is a valid zero value for all
unsigned integer types. (By saying "all bits zero", I refer to value both
representations bits and any superfluous bits)

The C99 standard doesn't say this; it was added in a TC. But yes,
that guarantee is effectively part of the standard.
 
O

Old Wolf

Jack said:
Research project: Locate at least one non-obsolete platform where a
combination of padding bits in an unsigned integer type actually
causes a trap or calculation error.

Does this include systems where each byte has a parity bit,
and the hardware traps if it detects a parity error in any
particular byte?
 
K

Keith Thompson

Jack Klein said:
And finally, as to the usefulness of worrying about padding bits in
integer types, I read Keith's post about working on a Cray else
thread. I never have, and Keith didn't say, but I'd be willing to bet
that the padding bits are simply ignored, and never cause any sort of
trap or unexpected error in a calculation.

I actually don't know one way or the other. (I might look into it if
I get sufficiently motivated.)
 
K

Keith Thompson

Old Wolf said:
Does this include systems where each byte has a parity bit,
and the hardware traps if it detects a parity error in any
particular byte?

Probably not. If a bit isn't visible when you view an object as an
array of unsigned char, it's not a padding bit (it's not a bit at all
as far as the C standard is concerned).
 
F

Frederick Gotham

Keith Thompson posted:

(It's a Cray Y/MP EL running Unicos 9.0, basically an obsolete
supercomputer.)


I think I read elsewhere on the newsgroup the unsigned integer types have
padding because the machine can really only do floating point
arithmetic...


So I'm curious, how would it deal with the following code?


int main(void)
{
unsigned char array[50];


const unsigned char * const p_over =
array + sizeof(array) / sizeof(*array);

const unsigned char* p = array;

do
{
*p++ = 46;
} while ( p != p_over );


}
 
K

Keith Thompson

Frederick Gotham said:
Keith Thompson posted:
(It's a Cray Y/MP EL running Unicos 9.0, basically an obsolete
supercomputer.)

I think I read elsewhere on the newsgroup the unsigned integer types have
padding because the machine can really only do floating point
arithmetic...


So I'm curious, how would it deal with the following code?


int main(void)
{
unsigned char array[50];


const unsigned char * const p_over =
array + sizeof(array) / sizeof(*array);

const unsigned char* p = array;

do
{
*p++ = 46;
} while ( p != p_over );


}

Probably by printing a compile-time error message. You declare p as a
pointer to const unsigned char, then attempt to modify what it points
to.

If you drop the "const" in the declaration of p, it will simply set
each element of array to 46 on any conforming implementation --
assuming the entire program isn't optimized away because it produces
no output.

I haven't tried it on the Cray, and I don't see the point of the
question. (The standard explicitly says that unsigned char has no
padding bits, but even if it did, the program doesn't have anything to
do with that issue.)
 
B

Barry Schwarz

Frederick Gotham said:
Keith Thompson posted:
(It's a Cray Y/MP EL running Unicos 9.0, basically an obsolete
supercomputer.)

I think I read elsewhere on the newsgroup the unsigned integer types have
padding because the machine can really only do floating point
arithmetic...


So I'm curious, how would it deal with the following code?


int main(void)
{
unsigned char array[50];


const unsigned char * const p_over =
array + sizeof(array) / sizeof(*array);

const unsigned char* p = array;

do
{
*p++ = 46;
} while ( p != p_over );


}

Probably by printing a compile-time error message. You declare p as a
pointer to const unsigned char, then attempt to modify what it points
to.

If you drop the "const" in the declaration of p, it will simply set
each element of array to 46 on any conforming implementation --
assuming the entire program isn't optimized away because it produces
no output.

Since p points to an element of array and none of those elements have
been initialized, this invokes undefined behavior at each iteration.


Remove del for email
 
K

Keith Thompson

Barry Schwarz said:
So I'm curious, how would it deal with the following code?


int main(void)
{
unsigned char array[50];


const unsigned char * const p_over =
array + sizeof(array) / sizeof(*array);

const unsigned char* p = array;

do
{
*p++ = 46;
} while ( p != p_over );


}

Probably by printing a compile-time error message. You declare p as a
pointer to const unsigned char, then attempt to modify what it points
to.

If you drop the "const" in the declaration of p, it will simply set
each element of array to 46 on any conforming implementation --
assuming the entire program isn't optimized away because it produces
no output.

Since p points to an element of array and none of those elements have
been initialized, this invokes undefined behavior at each iteration.

I don't think so. The statement
*p++ = 46;
assigns a value to the array element and increments p (the pointer,
not the array element).
 
B

Barry Schwarz

Barry Schwarz said:
So I'm curious, how would it deal with the following code?


int main(void)
{
unsigned char array[50];


const unsigned char * const p_over =
array + sizeof(array) / sizeof(*array);

const unsigned char* p = array;

do
{
*p++ = 46;
} while ( p != p_over );


}

Probably by printing a compile-time error message. You declare p as a
pointer to const unsigned char, then attempt to modify what it points
to.

If you drop the "const" in the declaration of p, it will simply set
each element of array to 46 on any conforming implementation --
assuming the entire program isn't optimized away because it produces
no output.

Since p points to an element of array and none of those elements have
been initialized, this invokes undefined behavior at each iteration.

I don't think so. The statement
*p++ = 46;
assigns a value to the array element and increments p (the pointer,
not the array element).
You're right. For some reason I read it as +=. I think I'll blame my
glasses.


Remove del for email
 
F

Frederick Gotham

Keith Thompson posted:

Probably by printing a compile-time error message. You declare p as a
pointer to const unsigned char, then attempt to modify what it points
to.


I rarely check over my code before posting to Usenet, so you can expect
to see the odd error or oversight here and there. More to the point, why
shift the focus away from the topic at hand, impertinently focusing the
attention on a misplaced "const"? It makes the exchange less enjoyable.

If you drop the "const" in the declaration of p, it will simply set
each element of array to 46 on any conforming implementation --
assuming the entire program isn't optimized away because it produces
no output.


Again, nothing to do with the actual topic at hand.

I haven't tried it on the Cray, and I don't see the point of the
question. (The standard explicitly says that unsigned char has no
padding bits, but even if it did, the program doesn't have anything to
do with that issue.)


Here's what I was getting at:

If the machine in question can only do floating-point arithmetic, and
if it achieves integral arithemic via usage of padding bits... then how
could it possibly do arithmetic on an unsigned char (because an unsigned
char is guaranteed to be absent of padding bits)?
 
C

CBFalconer

Frederick said:
.... snip ...

I rarely check over my code before posting to Usenet, so you can
expect to see the odd error or oversight here and there. More to
the point, why shift the focus away from the topic at hand,
impertinently focusing the attention on a misplaced "const"? It
makes the exchange less enjoyable.

Because, around here, we value accuracy, and we don't suffer the
goofs to live. Maybe you should do more checking before posting.
I don't think any regular has failed to be corrected at times. It
does tend to sharpen the critical faculties.
 
F

Frederick Gotham

CBFalconer posted:
Because, around here, we value accuracy, and we don't suffer the
goofs to live. Maybe you should do more checking before posting.
I don't think any regular has failed to be corrected at times. It
does tend to sharpen the critical faculties.


I have no problem with a simple correction:

"Hey, you've a misplaced const there".

But why proceed to center the post around an obvious oversight? If anything
it just demonstrates the poster's lack of proficiency to notice that it was
simply an oversight.
 
R

Richard Heathfield

Frederick Gotham said:
I have no problem with a simple correction:

"Hey, you've a misplaced const there".

But why proceed to center the post around an obvious oversight?

To get you out of the habit of posting obvious oversights, maybe? There is a
strong case to be made out for /only/ pointing out the /first/ error in any
code.
If
anything it just demonstrates the poster's lack of proficiency to notice
that it was simply an oversight.

That's the second time at least that you've attacked proficient C
programmers for criticising your C code's incorrectness. That isn't a
bright direction to be heading in, in my opinion.
 
K

Keith Thompson

Frederick Gotham said:
CBFalconer posted:



I have no problem with a simple correction:

"Hey, you've a misplaced const there".

But why proceed to center the post around an obvious oversight? If anything
it just demonstrates the poster's lack of proficiency to notice that it was
simply an oversight.

I certainly did not "center the post around an obvious oversight". I
pointed it out, then answered your question assuming the "const" is
deleted.

As I said in my previous response, I honestly didn't know what the
point of the program was. Next time, please check your code before
posting it, and if you're making a point, please state it rather than
assuming it's clear from the code.
 
K

Keith Thompson

Frederick Gotham said:
Keith Thompson posted:

I rarely check over my code before posting to Usenet, so you can expect
to see the odd error or oversight here and there. More to the point, why
shift the focus away from the topic at hand, impertinently focusing the
attention on a misplaced "const"? It makes the exchange less enjoyable.

If you make an error, expect to have it pointed out. If you make an
error because you didn't bother to check over your code before posting
it, expect to be flamed for wasting everybody's time.

[...]
Here's what I was getting at:

If the machine in question can only do floating-point arithmetic, and
if it achieves integral arithemic via usage of padding bits... then how
could it possibly do arithmetic on an unsigned char (because an unsigned
char is guaranteed to be absent of padding bits)?

I never said it can only do floating-point arithmetic. I think all I
said is that its design emphasizes floating-point performance over
integer performance. I actually don't know what it does on the
machine-code level, but the C implementation is, as far as I know,
conforming (C90, not C99). I think it does have instructions for
integer arithmetic.

The C compiler has CHAR_BIT==8, and it properly implements 8-bit
unsigned char with all the semantics required by the standard. It
probably goes through some extra gyrations to do this, but the details
are off-topic. The run-time behavior of the program you posted won't
illustrate anything in particular about the system. An assembly
listing might, but I'm not going to post one. If you're sufficiently
curious, you can get your own account at www.cray-cyber.org.

Perhaps I just should have said that some real C implementations have
padding bits for some integer types and left it at that.
 
D

Dik T. Winter

> Keith Thompson posted:
>
>
>
>
> I think I read elsewhere on the newsgroup the unsigned integer types have
> padding because the machine can really only do floating point
> arithmetic...

This is wrong. On the Cray a word is 64 bits (the smallest quantity that
can be loaded from and stored in memory. Single precision FP is sign
magnitude, 1 sign bit, 15 exponent bits and 48 mantissa bits. The
largest integers the machine can reliably handle are 48 bit integers.
(Multiplication is done in the multiply unit and for integer multiply only
the lower 48 bits are used.) So in an int there are 48 value bits and
16 padding bits. A char is 8 bits, but loading and storing elements of
char arrays is a bit tedious.
> So I'm curious, how would it deal with the following code?
>
> int main(void)
> {
> unsigned char array[50];
> const unsigned char * const p_over =
> array + sizeof(array) / sizeof(*array);
> const unsigned char* p = array;
> do
> {
> *p++ = 46;
> } while ( p != p_over );
> }

What is the relation with the initial remark? On the Cray it is just
compiled and if you wish executed.
 
D

Dik T. Winter

> If the machine in question can only do floating-point arithmetic, and
> if it achieves integral arithemic via usage of padding bits... then how
> could it possibly do arithmetic on an unsigned char (because an unsigned
> char is guaranteed to be absent of padding bits)?

Although beside the point (because that is not how the Cray works), it
is easy. In registers and memory an int has 16 padding bits and 48
value bits. In memory a char has 8 value bits and no padding bits.
In register a char has 56 padding bits and 8 value bits. Probably you
can work it out from this.
 
N

Nick Keighley

Frederick said:
It's also allowed in C++, which has the most modern standard of them all.

from www.research.att.com/~bs/C++.html
-------------------------------------------------------------
"The ISO [C++] standard has been finalized and adopted by unanimous
vote
Nov 14, 1997. It was ratified in August 1998"

http://en.wikipedia.org/wiki/C_programming_language
-----------------------------------------------------------------------------
"After a long and arduous process, the standard was completed in 1989
and ratified as ANSI X3.159-1989 "Programming Language C." This version
of the language is often referred to as ANSI C, or sometimes C89 (to
distinguish it from C99).

In 1990, the ANSI C standard (with a few minor modifications) was
adopted by the International Organization for Standardization (ISO) as
ISO/IEC 9899:1990. This version is sometimes called C90. Therefore, the
terms "C89" and "C90" refer to essentially the same language."


--
Nick Keighley

Many astrologers think that this concentration on [the sun-sign column]
has
done untold damage to serious astrology.
The Independent
 
E

ena8t8si

Robert said:
Till said:
Hi,

I stumbled upon the following code to determine byte ordering in the FAQ:

union {
int i;
char c[sizeof(int)];
} x;
/* do stuff */

In this case it seems that the union was used to convert a memory section
from int to char[]. However I've learned that you couldn't use unions to
reinterpret a memory area, because you can't always be sure that the
fields realy do use the same positions. So why is this code portable?

It's not portable but not for the reason you mentioned. There cannot
be padding before the elements of a union, the first byte of a union is
the first byte of each of its members, always. The problem is that
retrieving the value of a union element is only defined when the member
retrieved was the member most recently assigned, so assigning i and
then examining c is not defined.

Please see DR 283 and its proposed TC:

Attach a new footnote 78a to the words "named member" in 6.5.2.3#3:

78a If the member used to access the contents of a union object is
not the same as the member last used to store a value in the
object,
the appropriate part of the object representation of the value is
reinterpreted as an object representation in the new type as
described
in 6.2.6 (a process sometimes called "type punning"). This might be
a
trap representation.
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top