Eric Sosman ha scritto:
Actually I am a bit confused about one thing:
at what degree a C compiler is indipendent from the
operating system it is running on? I mean, for example,
the time_t type is implemented in gcc or in glibc? gcc
compiler (but i may think about other compilers)
completely relies on glibc or it has its own
indipendent static libraries with different requirements
from Posix (or Windows)?
We have to distinguish between the cross-platform definition
of C and the realizations of C on a particular platform or family
of platforms.
The Standard describes the features of C that are common to
all platforms. It also describes which features are optional (e.g.,
int36_t is not required to be present), and the permitted variations
among features (e.g., whether char is signed or unsigned). But,
after taking the allowed freedoms into account, the Standard describes
"fully portable C."
Any particular implementation of C will, for starters, make the
choices the Standard has left open: The underlying type of time_t,
the numeric value that encodes 'x', and so on. It is also likely
to add further specifications: The allowed syntax for file names in
fopen(), how time_t is encoded, the meanings of exit() arguments
beyond those specified in the Standard, and the like. It may add
features not mentioned in C's definition, like memory-mapped files
and network facilities. The result is a "platform-specific C."
It is up to you as a programmer to find an appropriate balance
between "fully portable" and "platform-specific" characteristics,
and the choices will be different for different projects. You may
write a piece of code that does something highly specific to the
Frobozz Magic C implementation on the DeathStation 9000, and is of
interest only in FMC/DS9K environments: In that case, there's little
reason to avoid using FMC/DS9K-specific features. On the other hand,
you might write code that parses the command-line arguments of main()
in a certain way, and you'd like to use this code in many programs on
many environments: In that case, you'd be well-advised to stick as
closely to "fully portable" C as you can. And there are intermediate
positions, too: You can write for a platform family (like POSIX or
Win32) that provide features available in several environments but
aren't necessarily present in C implementations outside the family.
As for whether time_t is a creature of the compiler or of the
library, the Standard's view is that both the compiler and the library
are part of "the implementation," so the question isn't answerable.
The language is the language, and it includes the library (except for
free-standing implementations, which I'll just avoid talking about).
But again, when you get to a particular realization of C on a
particular platform, the division between compiler and library gets
clearer. In the case of gcc/glibc, it is almost certainly glibc's
business to choose an appropriate representation for time_t and to
"publish" its choice in <time.h> so the compiler can then know how
to deal with it. But some fuzziness quite likely remains: If you
call sqrt(), for example, "compiler magic" may generate a square-
root instruction right there in the middle of your code, rather
than generating a call to a square-root function in the library.
There's fuzziness the other way, too: Some machines lack hardware
support for integer division, so `m / n' may wind up as a call to
a hidden library function. And there's some areas where the library
and the compiler must "conspire" to get the right effect: setjmp()
and longjmp(), for example, are probably not completely library- nor
completely compiler-implemented.
So: When you ask whether thus-and-such a feature is a creature
of the compiler or of the library, (1) from the fully portable point
of view the question makes no sense, and (2) from the point of view
of a particular implementation or family of implementations the
question is probably answerable, at least in part.