By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,934 Members | 1,677 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,934 IT Pros & Developers. It's quick & easy.

compilation file dependency

P: n/a
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.

If I use a flag that will not link the code, order of compilation is not an
issue, right? I am not that familiar with compilers so I am not sure. It
seems to me that it would not make a difference as to *which* file was
compiled *when*. Dependencies are only an issue during linking?

Thanks, Mike
Nov 14 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Michael Gaab wrote:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.

If I use a flag that will not link the code, order of compilation is not an
issue, right? I am not that familiar with compilers so I am not sure. It
seems to me that it would not make a difference as to *which* file was
compiled *when*. Dependencies are only an issue during linking?

Thanks, Mike


The only compilation dependencies are the declarations. The
declarations must be processed before the statements. Other than
that, each "file" is treated as an independent translation unit.

The linking phase is used to resolve any external references from
a translation unit. Some tools require the files specified in
a special order before linking. All the external references
must be resolved before creating an executable image.

Many projects will have source units translated into "object"
units. The final phase consists of "linking" these object
units to form an executable image. If an object unit is not
modified, its source unit will not be translated, thus
speeding up the "build". However, some tools will only
produce debugger symbols from compiled units. :-(

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Nov 14 '05 #2

P: n/a
On Wed, 10 Dec 2003 12:18:07 -0600, "Michael Gaab"
<mi****@montana.com> wrote in comp.lang.c:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.

If I use a flag that will not link the code, order of compilation is not an
issue, right? I am not that familiar with compilers so I am not sure. It
seems to me that it would not make a difference as to *which* file was
compiled *when*. Dependencies are only an issue during linking?

Thanks, Mike


Actually the C standard specifically defines 8 stages of translation,
but linking is indeed the final one. Nothing in the C standard allows
for a difference based on when or in what order individual translation
units pass through the first 7 stages.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Nov 14 '05 #3

P: n/a

"Michael Gaab" <mi****@montana.com> wrote in message
news:3f********@127.0.0.1...
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.


Great but what about the profiler. Isn't profiling in there somewhere?

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
Nov 14 '05 #4

P: n/a
Michael Gaab wrote:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.

If I use a flag that will not link the code,
order of compilation is not an issue, right?
I am not that familiar with compilers so I am not sure.
It seems to me that
it would not make a difference as to *which* file was compiled *when*.
Dependencies are only an issue during linking?


The compiler calls the link editor to link together the object files
left behind by the assembler.
The link editor doesn't care when the file was compiled either.
You just tell it which [object] files to link together
and it will resolve all of the links.
You just need to make sure that the link editor
knows how to find all of the object files.
The compiler passes the location of standard library archives
to the link editor along with the location of the object files
left behind by the assembler. The location of other object files
or library archives that are required to resolve all of the links
must be specified explicitly so that they can also be passed
along to the link editor.

Nov 14 '05 #5

P: n/a
Bill Cunningham wrote:

"Michael Gaab" <mi****@montana.com> wrote in message
news:3f********@127.0.0.1...
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.


Great but what about the profiler. Isn't profiling in there somewhere?

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----


No.

--
Les Cargill
Nov 14 '05 #6

P: n/a
Michael Gaab <mi****@montana.com> scribbled the following:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.


Wouldn't it be possible (although not mandatory) to skip phase 3?
AFAIK preprocessing transforms C to C, and compilation transforms C to
another language. Assembly would be transforming this another language
to yet another language. Why not transform C directly into this yet
another language?
Linking would still be necessary, to allow for multiple translation
units. An unlinked object file is full of object references, that can
be thought of saying: "An object with this name, of this type, but I
don't know where it is". Linking simply finds out where these objects
are, and replaces the object references with their addresses.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"I am not very happy acting pleased whenever prominent scientists overmagnify
intellectual enlightenment."
- Anon
Nov 14 '05 #7

P: n/a
begin Joona I Palaste:
Michael Gaab <mi****@montana.com> scribbled the following:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.


Wouldn't it be possible (although not mandatory) to skip phase 3?


Sure.

Borland C reached it's famous spead by doing steps 1 to 3 in one go.
This had the additional advantage that the pre-processor was fully
aware of C and could handle things like sizeof(int) in #if.

--
Für Google, Tux und GPL!
Nov 14 '05 #8

P: n/a
Alexander Bartolich <al*****************@gmx.at> scribbled the following:
begin Joona I Palaste:
Michael Gaab <mi****@montana.com> scribbled the following:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.
Wouldn't it be possible (although not mandatory) to skip phase 3?

Sure. Borland C reached it's famous spead by doing steps 1 to 3 in one go.
This had the additional advantage that the pre-processor was fully
aware of C and could handle things like sizeof(int) in #if.


Thanks, this was more or less what I was thinking. I don't know anything
about Borland specifics but I thought that doing steps 2 and 3 in one go
was fully possible.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"We sorcerers don't like to eat our words, so to say."
- Sparrowhawk
Nov 14 '05 #9

P: n/a
>>> Michael Gaab <mi****@montana.com> scribbled the following:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.

[As someone else noted elsethread, the C standard specifies eight,
not four, phases -- but typically various ones are combined in a
single "user-visible" step.]
begin Joona I Palaste:
Wouldn't it be possible (although not mandatory) to skip phase 3?
Alexander Bartolich <al*****************@gmx.at> scribbled the following:
Sure.
Borland C reached it's famous spead by doing steps 1 to 3 in one go.
This had the additional advantage that the pre-processor was fully
aware of C and could handle things like sizeof(int) in #if.


Of course, Standard C forbids "handling" sizeof(int) in #if
expressions, because by this phase keywords do not yet exist --
the only tokens are "preprocessing tokens" (pp-tokens), which are
actually more general than C tokens, and no pp-token is a keyword.
(The pp-token "defined" is recognized in #if expressions, but is
not a "keyword" in the Standard's sense.) Since both sizeof and
int are keywords, the preprocessor is not supposed to know about
them. Moreover, in #if expressions, sizeof and int match the format
allowed for identifiers, so if they are not already #define'd to
some expansion, they must behave as does any other undefined
identifier, and be considered identical to an integral constant
zero:

#if sizeof ( int ) == 2

and

#if 0 ( 0 ) == 2

are quite literally identical in this context. The latter is a
syntax violation and must draw a diagnostic. (Note that once the
one required diagnostic comes out, THEN the compiler can go back
and re-interpret the line and turn "sizeof" and "int" into keywords,
though!)

This "undefined identifier acts like 0" is sometimes quite annoying,
as it might be nice to get diagnostics for typos:

#define LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321
#define PDP_ENDIAN 3412

#define BYTE_ORDER LITTLE_ENDIAN

/* many lines later */
#if BYTE_ODRER == LITTLE_ENDIAN
... some code here ...
#endif

This translates in the same manner as "#if 0 == LITTLE_ENDIAN",
because of the transposition error in turning BYTE_ORDER into
BYTE_ODRER. (Of course, a "high quality" compiler might have an
optional warning anyway.)

In article <br**********@oravannahka.helsinki.fi>
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:Thanks, this was more or less what I was thinking. I don't know anything
about Borland specifics but I thought that doing steps 2 and 3 in one go
was fully possible.


Indeed, doing all eight translation phases in one go is *also*
possible. Separate compilation, in such a system, is handled by
recording the files to compile (and perhaps doing a pre-scan to
check for errors that might be easy to discover early). The trick
is not so much "what is possible", but rather "what is the most
practical and useful" -- and it turns out that a number of different
approaches have a number of different advantages and disadvantages.
On systems with multiple CPUs, it can be fastest, as measured by
"stopwatch time", to run many separate translation phases, one on
each CPU. A traditional Unix-like "cpp | cc1 | as" sequence can
run on three separate CPUs, with all three doing useful work at
the same time and producing results twice as fast (as measured by
stopwatch) as an all-in-one-process compiler.

As another example, the Plan 9 C compiler defers actual code
generation to link-time, so as to be able to do global register
allocation -- i.e., global variables can wind up in registers, or
a register can be shared between two or three functions even if
they are in separate .c source files -- and other such optimizations.
This turns out to be a strong disadvantage sometimes, because
compiling 100 or so modules takes, e.g., two seconds in the "compile"
stage (running on eight CPUs) and then 30 seconds in the "link"
stage (on one CPU). Had more work been done in the "compile" stage,
the eight CPUs could have taken, say, 6 seconds, leaving only two
or three seconds of work to do in the "link" stage. The code might
run somewhat slower, but one could then have a compile-time switch
for "how much to defer".
--
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.
Nov 14 '05 #10

P: n/a
On 14 Dec 2003 21:45:53 GMT, Joona I Palaste <pa*****@cc.helsinki.fi>
wrote:
Michael Gaab <mi****@montana.com> scribbled the following:
Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.


Wouldn't it be possible (although not mandatory) to skip phase 3?
AFAIK preprocessing transforms C to C, and compilation transforms C to
another language. Assembly would be transforming this another language
to yet another language. Why not transform C directly into this yet
another language?


Certainly possible. The Watcom compiler, for example, compiles to
binary. If you ask for assembler source, it invokes a dis-assembler.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #11

P: n/a
>Compilation in c generally has four phases
1. Preprocessing
2. Compilation
3. Assembly
4. Linking.

If I use a flag that will not link the code, order of compilation is not an
issue, right?
It depends on the build procedure for the application in question.
For some applications (gcc comes to mind, at least some versions
of it), it is necessary to Preprocess, compile, assemble, link, and
*RUN* a program to produce a header file necessary to preprocess a
file used in the creation of another program.

On occasion the build procedures get really tricky. With compilers
themselves, it is not uncommon to have steps:

1. Compile the source using the native compiler creating stage-1.
2. Compile the source using stage-1 creating stage-2.
3. Compile the source using stage-2 creating stage-3.
4. Verify that stage-2 and stage-3 are identical (modulo things
like time stamps embedded in the executable). If it is not,
something is broken. It is not at all unusual, however, to have
stage-1 and stage-2 different.

I am not that familiar with compilers so I am not sure. It
seems to me that it would not make a difference as to *which* file was
compiled *when*.
For simple situations, this is true. When code is dynamically
generated from something else, it may not be. You may need to link
and run something in order to create the source code needed for
another part of the package. Or, the program may have to "bootstrap"
itself. Consider a klutzenmeyer compiler (which generates C as
output) written partly in klutzenmeyer.
Dependencies are only an issue during linking?


Gordon L. Burditt
Nov 14 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.