Plauger, size_t and ptrdiff_t

J

Jordan Abel

Change the standard so that malloc() "takes as an argument an integral type
of type int or higher".

Therefore if you have a machine with a huge memory and small ints, the
compiler writer is free to say that malloc() should take an unsigned long
long, or whatever.

However anyone can write code with int s as array indices, and know that it
is portable - the huge array user is the one making the non-portable
assumption.

Usually you never want to allocate more memory than can be held in an
intger, and of the excpetions usually you wnat to make only one, very
program and platform-specific, allocation.

Some leeway for the types of arguments in general would be nice,
actually - for example, it'd be nice if fseek() could take an off_t on
unix systems, eliminating the need for the non-standard fseeko()
function.
 
K

Keith Thompson

Jordan Abel said:
Some leeway for the types of arguments in general would be nice,
actually - for example, it'd be nice if fseek() could take an off_t on
unix systems, eliminating the need for the non-standard fseeko()
function.

off_t isn't necessarily an integer type; it's "an object type other
than an array type capable of recording all the information needed to
specify uniquely every position within a file". The non-standard
fseeko() is identical to fseek() except that it takes an off_t rather
than a long; I think that it's supported only on systems where off_t
is an integer type. (Note that fpos_t also has to store the file's
parse state, of type mbstate_t.)

What's needed for fseek() and ftell() isn't more leeway, it's a better
definition. The problem is that they're unnecessarily tied to one
particular predefined integer type, long, that isn't necessarily big
enough for the purpose.

A better solution would be to add a new typedef (fseek_t?) for an
integer type to be used for the offset argument of fseek() and the
result of ftell(). Using long int was reasonable in C90, in which
long int was the largest integer type. In C99, though, we have a
requirement for a 64-bit type, but long int can still reasonably be 32
bits even on systems that support multi-gigabyte files. I think
continuing to use long int for fseek() and ftell() was a mistake on
the part of the C99 committee (unless such a change would have broken
existing code).

64-bit file sizes should be adequate for a long time.
 
J

Jordan Abel

off_t isn't necessarily an integer type; it's "an object type other
than an array type capable of recording all the information needed to
specify uniquely every position within a file"

You're thinking of fpos_t. off_t is a signed integral type. It's in
posix, there is of course no such thing in standard C.
The non-standard fseeko() is identical to fseek() except that it takes
an off_t rather than a long; I think that it's supported only on
systems where off_t is an integer type. (Note that fpos_t also has to
store the file's parse state, of type mbstate_t.)

What's needed for fseek() and ftell() isn't more leeway, it's a better
definition. The problem is that they're unnecessarily tied to one
particular predefined integer type, long, that isn't necessarily big
enough for the purpose.

A better solution would be to add a new typedef (fseek_t?) for an
integer type to be used for the offset argument of fseek() and the
result of ftell().

That's what off_t is for in posix.
Using long int was reasonable in C90, in which long int was the
largest integer type. In C99, though, we have a requirement for a
64-bit type, but long int can still reasonably be 32 bits even on
systems that support multi-gigabyte files. I think continuing to use
long int for fseek() and ftell() was a mistake on the part of the C99
committee (unless such a change would have broken existing code).

The problem is that existing code is permitted to declare, say,
extern long ftell();

The question is how much existing code does such a thing, and how much
is it permissible to break. _any_ new change can break existing code.
C99 breaks existing code that uses inline as an identifier, IIRC.
 
K

Keith Thompson

Keith Thompson said:
off_t isn't necessarily an integer type; it's "an object type other
than an array type capable of recording all the information needed to
specify uniquely every position within a file". The non-standard
fseeko() is identical to fseek() except that it takes an off_t rather
than a long; I think that it's supported only on systems where off_t
is an integer type. (Note that fpos_t also has to store the file's
parse state, of type mbstate_t.)

The fseeko() and ftello() functions are defined by POSIX (or at least
by The Open Group Base Specifications Issue 6, which I think is
basically the same thing). POSIX also requires off_t to be a signed
integer type. I don't know whether it would be practical for a future
version of the C standard to require this as well (I frankly don't
understand the multibyte/wide character stuff very well); doing so
might break things for some non-POSIX systems.
 
K

Keith Thompson

Jordan Abel said:
You're thinking of fpos_t. off_t is a signed integral type. It's in
posix, there is of course no such thing in standard C.

You're right of course. Stupid mistake on my part. That'll teach me
to post while using a rented brain.

As mentioned elsewhere, off_t is POSIX-specific and is required to be
an integer type.
That's what off_t is for in posix.

Right. So it seems to me that making off_t a system-specific typedef
for a signed integer type, and using it rather than long int for
fseek() and ftell(), would have been a really good idea. In other
words, adopt POSIX's fseeko() and ftello(), but call them fseek() and
ftell(). On most modern systems, then, off_t would be a 64-bit
integer type (probably an alias for long long).

fpos_t, fgetpos(), and fsetpos() would presumably be left as they are.
The problem is that existing code is permitted to declare, say,
extern long ftell();

The question is how much existing code does such a thing, and how much
is it permissible to break. _any_ new change can break existing code.
C99 breaks existing code that uses inline as an identifier, IIRC.

Yes, along with restrict (the new keywords _Bool, _Complex, and
_Imaginary can't conflict with any strictly conforming program; I
guess the committee decided _Inline and _Restrict were just too ugly.

Any *sane* program will just use "#include <stdio.h>", of course. In
fact, I'm not sure it's possible to use feek() and ftell() without a
"#include <stdio.h>", since each takes an argument of type FILE*.

A change would also affect any program that uses a function pointer
that points to either fseek() or ftell(), which might be reasonable if
you want to determine at run time whether to call the standard
function or one with the same type (say, a dummy or wrapper function).

If concern for backward compatibility prevents changing the types of
fseek() and ftell(), I suppose a future C standard could just add
fseeko(), ftello(), and off_t from POSIX, and deprecate fseek() and
ftell(). Unfortunately, that would make the set of positioning
functions even more cluttered than it already is.

Did C99 change the types of any C90 library functions while leaving
their names as they were?
 
D

Dave Thompson

Did C99 change the types of any C90 library functions while leaving
their names as they were?

_If_ you #include <tgmath.h> sin() etc. become generic. But that's a
new header no C90-conforming program will have used.

- David.Thompson1 at worldnet.att.net
 

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
474,175
Messages
2,570,947
Members
47,498
Latest member
yelene6679

Latest Threads

Top