sizeof C integral types

P

pete

Arthur said:
However, re: Dan's reply: getchar() returns either a 'char'
value, cast to 'int', or it returns EOF, which is a negative 'int'
value unequal to any 'char' value. Right?
My #definitions above provide exactly enough numbers to do this
job: the range of 'char', which is signed, goes from -32767 to 32767,
and EOF is the 'int' value -32768. So if you were talking only about
the "EOF-and-getchar issue," you were wrong, AFAICT.

Similar issue.
On my system the return value of putchar(EOF) is greater than -1.
I think it's supposed to be greater than -1,
and I don't think that it can be, on your system.
I think
I'm really going to need the C&V here, or you're going to have to
show me a piece of code that pokes large holes in my #definitions.

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
int r;

r = putchar(EOF);
if (r > -1) {
puts("putchar(EOF) is greater than -1 on my system.");
}
return 0;
}

/* END new.c */
 
A

Arthur J. O'Dwyer

On my system the return value of putchar(EOF) is greater than -1.
I think it's supposed to be greater than -1,
and I don't think that it can be, on your system.

[compressed pete's code]
#include <stdio.h>
int main(void) {
int r = putchar(EOF);
if (r > -1)
puts("putchar(EOF) is greater than -1 on my system.");
return 0;
}

Hmm... yes... on my hypothetical system, this would replace EOF
by -32768, convert -32768 to uchar 32768, print that value out,
and then try to return 32768 as an 'int'. That would not be
possible, hence my system would not be conforming. So I do
believe you've poked holes in it.

So, from the getchar() spec, 'int' must range over all 'char'
values plus EOF, and from the putc() spec, 'int' must range over
all 'unsigned char' values plus EOF. So I guess Dan Pop is right
after all... surprise surprise. ;-)

-Arthur
 
P

Peter Nilsson

Dan Pop said:
In <[email protected]> "Arthur J.
O'Dwyer said:
Nor do I. And even though I at first thought it was technically
wrong because of padding bits, I now think that while it still may be
wrong, it's less wrong than I thought.

a) Plain char is unsigned. INT_MAX must be at least UCHAR_MAX so that
getchar() can return any plain char value, and INT_MIN must be less than
or equal to -32767. So the total number of values of 'int' must be at
least UCHAR_MAX+32768, which requires more bits than CHAR_BIT. Q.E.D.

b) Plain char is signed. The range of char, i.e., of signed char, must
be a subrange of the range of int. But is it possible we might have

The properties of plain char don't matter, it is unsigned char that
matters.
#define CHAR_BIT 16
#define UCHAR_MAX 65535
#define SCHAR_MIN -32767 /* !!! */
#define SCHAR_MAX 32767
#define INT_MIN (-32767-1) [corrected]
#define INT_MAX 32767
#define EOF (-32767-1) [corrected]

Is anything wrong, from the C standpoint, with these definitions?

Yes, for a hosted implementation: int cannot represent the whole range
of unsigned char.

Assuming int representation is 2C and the conversion of unsigned char to int
is the obvious (usual) one, where's the problem? (From an implementation
conformity point of view.)
 
D

Dan Pop

However, re: Dan's reply: getchar() returns either a 'char'
value, cast to 'int', or it returns EOF, which is a negative 'int'
value unequal to any 'char' value. Right?

Wrong! getchar() returns either an unsigned char cast to int, or EOF,
which has a negative value. The chapter and verse actually come from
the fgetc specification:

2 If the end-of-file indicator for the input stream pointed to by
stream is not set and a next character is present, the fgetc
function obtains that character as an unsigned char converted
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
to an int and advances the associated file position indicator
^^^^^^^^^
for the stream (if defined).

The conversion between unsigned char and int has a well defined
result only if the type int can represent the value being converted.
I hope this clarifies the issue.

Dan
 
D

Dan Pop

<snip>

Would anything be wrong with intentional under-using the potential range
#define CHAR_BIT 1024
#define UCHAR_MAX 255
#define SCHAR_MIN -127
... etc ...
#define <under-used limits for int, long ...>

Underusing is allowed for any type *except* unsigned char (and plain char,
if behaving as unsigned char). UCHAR_MAX *must* be 2 ** CHAR_BIT - 1 for
*any* conforming implementation. The reason is simple: unsigned char is
supposed to be suitable for accessing the implementation's byte, so if
the byte has CHAR_BIT bits, unsigned char must be able to access each
of them.

It is still possible to underuse the hardware byte, but, in this
case, the definition of CHAR_BIT must still reflect the size of the
implementation byte and not the size of the hardware byte. In your
example, CHAR_BIT would have to be defined as 8, even if the hardware
byte had 1024 bits. And wider types could only use the same bits
that unsigned char can access, because unsigned char is supposed to
be suitable for inspecting/altering their representation.

Dan
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top