Re: Behavior of the code
- From: Chris Torek <nospam@xxxxxxxxx>
- Date: 29 Dec 2007 02:12:03 GMT
In article <fl46kj$3qg$2@xxxxxxxx> jacob navia <jacob@xxxxxxxxxx> wrote:
[code using "%hhx" format in printf()]
That was the whole problem. hhx is defined in C99 only.
What is surprising is that the gcc printf recognizes somehow hh, even
if it doesn't support it. Strange.
It is not really surprising, or at least, *should* not be, if you
think about it. The GNU compiler collection contains a "C compiler"
(of sorts), but not a complete *implementation* of C, because it
uses whatever libraries are provided by the underlying system.
The compiler front-end, which reads the source code and turns
syntax and semantics into instruction sequences, is all part of
this "compiler collection". While this part does not actually
implement C99, it comes close enough to "understand" %hhx. So
the part of the compiler that emits diagnostics will "read" the
formatting directives to printf, see "%hhx", and check that the
argument has the correct type, all while *assuming* that the
system-provided library will "do the right thing" with it.
Later, at link time, when you combine the "compiled" code (object
files and/or libraries) with the system-provided library to get
the final executable -- Translation Phase 8 in the C99 standard
(TP7 in C89, if I remember right) -- you get the system's actual
implementation of printf(), which is often "less C99-ish" (as it
were) than even GCC.
It is not practical for GCC to provide the implementation of
printf() itself: The bottom levels of stdio are full of
"implementation-specific magic" (such as handling all the RMS
formats on VMS, or the multiple kinds of file formats on IBM
mainframes or DOS/Windows systems) that varies too much from one
implementation to the next. You can, of course, just choose to
use a system whose system-provided C library supports %hhx. :-)
(The C Standards really address only complete systems, not divided-up
half-implementations[%] like the GNU Compiler Collection. So one
cannot even say that gcc implements C89, much less that it implements
C99. If you combine gcc with a particular set of libraries, you
can get a conformant C89 implementation, but gcc is approaching
C99 in the front-end only asymptotically. The biggest sticking
point appears to be various GNU extensions that are incompatible
with C99: making the front end C99-conformant would break those.
Given that the GNU folks have broken their own extensions before,
I am not sure how "sticky" a sticking point this really is, but it
is definitely "sticky". :-) )
[% Actually, I tend to think of gcc as a "3/4ths or so" implementation.
Compilers are usually divided, in compiler circles at least, into
three parts. Only two of these are thought of as "the compiler":
the "front end", which reads syntax and "understands" semantics,
and the "back end", which does code-generation and final (peephole)
optimization. The main body of optimization is either part of the
"front end" or, in many cases now, a "middle end" that -- like the
back end -- is shared between multiple languages. That is, one
might have a front end for Ada, another for C, a third for C++, a
fourth for Fortran, and a fifth for Pascal; these would all produce
some sort of internal tree or list representation that feeds through
a shared optimizer and shared back-end. The "middle end" optimization
needed tends to vary quite a bit from one language to the next,
though, so it can be more efficient, in some senses, to paste
different "middle ends" onto the various front-end parts. Back
when 8 megabytes was a lot of RAM, this kind of efficiency was
more important; nowadays the gigantic shared middle end, that uses
a gigabyte of RAM to run, seems to be in vogue. :-)
In any case, after the final code comes out of the "back end"
of the compiler -- and in some cases, is turned into linkable
object code by a separate "assembler" -- the object code and
libraries are handled by a piece usually called a "linker". The
"linker" is normally completely separate from the compiler, and
tends to be used on its own now and then, e.g., to build
libraries.
(There are also "globally optimizing" compilers that defer at least
some of the optimization and code-generation phases. In this case,
instead of generating object code and linking that, the front end
simply saves a "digested form" of the code in the "object" files
-- which are no longer object files at all -- and the optimization,
code generation, and final stages are all run when you "link" the
pieces together. This gives the optimizer a view of the entire
program, so that it can do a much better job. The drawback is that
the "final link phase", which is usually pretty fast, now contains
most of the real work, and can take hours or even days for large
programs.)
The GNU Compiler Collection provides front and back ends, but
not the linker. There *is* a GNU linker, and using it buys you
some advantages, especially in languages other than C, but gcc
can be built for systems that use the native non-GNU linker,
using an auxiliary step they call "collect2".]
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
.
- Follow-Ups:
- Re: Behavior of the code
- From: Army1987
- Re: Behavior of the code
- References:
- Behavior of the code
- From: somenath
- Re: Behavior of the code
- From: jacob navia
- Re: Behavior of the code
- From: Army1987
- Re: Behavior of the code
- From: jacob navia
- Behavior of the code
- Prev by Date: Re: getting around lack of bool type support
- Next by Date: Re: Programming in standard c
- Previous by thread: Re: Behavior of the code
- Next by thread: Re: Behavior of the code
- Index(es):
Relevant Pages
|
|