Re: Just curiosity about some constructs
- From: Eric Sosman <eric.sosman@xxxxxxx>
- Date: Tue, 31 Jan 2006 10:54:51 -0500
Sensei wrote On 01/31/06 10:01,:
> Hi again!
>
> I have still curiosity about the reason of some C constructs/keywords...
>
> The first is about static functions. What was the reason of restricting
> a function to be visible just in a specific source file? Wasn't it
> sufficient not to be given a prototype (for visibility)?
No; you are confusing "scope" and "linkage." Without
`static', a function identifier has "external linkage," which
means that the name can refer to only one thing in the entire
program, no matter how many translation units are used. If
you have `void foo(void) {...}' in one file and in another
you write `double foo(char *ptr) {...}', the identifier has
external linkage in both and the two uses clash. With `static',
the identifier has "internal linkage," meaning that it does
not clash with any uses of `foo' (external or internal) in
other translation units.
A typical use is for a translation unit ("module") to
define some number of functions (and/or variables) with
external linkage, so code in other translation units can
refer to them. Meanwhile, "helper" functions (and/or
variables) are declared `static' so other modules cannot
refer to them and so their names won't clash with identifiers
used in those other modules. Think of `static' in this
sense as meaning "private."
> What about register and volatile variables? Was at that time a compiler
> not smart enough to optimize with in-register variables? And why would
> someone suggest the compiler not to optimze by making a variable
> volatile?
Compilers today are much better at optimizing than those
of the past. This is partly because of advances in the state
of the art, but mostly because the machines that run the
compilers are much larger and faster than those of the past.
The computations a modern compiler makes while performing its
optimizations would have taken far too much time and memory
to make them feasible on machines with 64KB of memory and a
250KHz CPU. `register' was a helpful hint to resource-strapped
compilers; nowadays it is largely useless.
`volatile' is a different matter, and is still relevant.
It tells the compiler that it is not safe to optimize the
accesses to a variable, usually because the variable can
change for reasons outside the compiler's knowledge or because
the act of making the access has some side-effect the compiler
cannot know about. One common example is the use of memory
locations that connect to I/O control registers, hardware
clocks, and so on. You might write a delay loop like
while (*hardware_timer < target_time)
;
.... and you'd be, er, "disappointed" if the compiler turned
this into the equivalent of
if (*hardware_timer < target_time)
while (1)
;
.... by optimizing away the "redundant" fetches of the value.
Similarly, you might control an I/O device by writing a
series of command codes to a special location:
*control_word = SEEK_TO_CYLINDER + cyl_num;
*control_word = START_WRITING;
.... and you'd be disappointed again if the compiler decided
to discard the first assignment on the grounds that the
value would be immediately overwritten by the second.
> Last question! This is about the switch statement. The statement seems
> to me to be completely different from others. Let me explain with an
> example. A while(condition) will execute the statement after the
> while(), and if someone wants to have more instructions to be executed
> in the loop, then { } should be used. This is true also for if/else,
> do/loop, but not with the switch. A case does not require any { } to
> execute more than one instruction, moreover, a brake must be given to
> make a single case being executed, otherwise all the following
> non-brake case statements will be executed. Why wasn't the switch like
> the others with { } and automatic brake?
The case labels in a `switch' are exactly that: labels
for single points in the code, not identifiers of regions
of code. That makes it easy to send several values to the
same piece of code:
switch (character) {
case ' ':
case '\t':
case '\n':
case '\f':
case '\r':
process_white_space();
break;
case '.':
case ',':
case ':':
process_punctuation();
break;
...
}
Many languages have a construct of this general flavor, not
all with quite the same rules. Why dmr chose this particular
scheme is a question only he can answer. His choice has been
both widely criticized and widely applauded.
--
Eric.Sosman@xxxxxxx
.
- References:
- Just curiosity about some constructs
- From: Sensei
- Just curiosity about some constructs
- Prev by Date: Re: hi
- Next by Date: Re: how to develop library ( .a and .so files) ! URGENT!!!
- Previous by thread: Just curiosity about some constructs
- Next by thread: Re: Just curiosity about some constructs
- Index(es):
Relevant Pages
|