473,396 Members | 1,998 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Just curiosity about some constructs

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)?

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?

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?

It's probably useless, but not for curiosity...

--
Sensei <se******@mac.com>

Part of the inhumanity of the computer is that, once it is competently
programmed and working smoothly, it is completely honest. (Isaac Asimov)

Jan 31 '06 #1
11 1585


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.

--
Er*********@sun.com

Jan 31 '06 #2
Sensei wrote:
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)?
If you don't make the function `static`, at the linking stage it may be
"found" by the linker looking for a function of the same name in the
object files provided, even if you did not provide its prototype in
other source files. To ensure your function is never "found" in this
way (i.e. is accessible only to other functions within the same source
file) you declare it `static`.
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?
The `register` variables were introduced at the time when compilers
were not as good at optimising, you got that one correctly.

The `volatile`, however, does /not/ mean "do not optimise". It means
"this variable may change behind your back, through no action of your
program, so do not make any assumptions about its value". In most, but
not all, cases this does in effect prevent the compiler from optimising
bits of code that refer to a `volatile` variable.
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?
I'm sure someone will correct me if I'm wrong, but I think that the
philosophy of the `switch` statement has historical reasons, or some
rationale that today, and if you don't know "the story of C", does not
make much sense. However, I do not think that the way it works is in
any way "wrong" or "strange", just "not as expected, or usual, given
other programming languages in existence today". IMHO, in many cases,
the way it works is actually preferrable. The only downside I can think
of is some extra typing for `break` statements (but you save on /not/
typing the braces! ;-) ).
It's probably useless, but not for curiosity...


I don't quite follow your thought here...

Cheers

Vladimir

Jan 31 '06 #3
On 2006-01-31 17:01:29 +0100, "Vladimir S. Oka" <no****@btopenworld.com> said:

It's probably useless, but not for curiosity...


I don't quite follow your thought here...


Well, questions like this one can be seen as useless. I asked this just
for curiosity, not for any ``higher'' intention... :)

--
Sensei <se******@mac.com>

Part of the inhumanity of the computer is that, once it is competently
programmed and working smoothly, it is completely honest. (Isaac Asimov)

Jan 31 '06 #4
>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. The names would still conflict at link time.
And early C had no prototypes, per se, although there were
declarations which declared the return type (but not argument types).
What about register and volatile variables? Was at that time a compiler
not smart enough to optimize with in-register variables?
Yes, and sometimes people wanted to give the compiler hints
that the default optimization wasn't doing the best it could.
And why would
someone suggest the compiler not to optimze by making a variable
volatile?
Because the variable can be changed by *SOMETHING ELSE*. Either
the variable isn't memory but a hardware register, or it's modified
by a signal handler, another thread, etc.

while (siop->statusregister & TX_BUFFER_EMPTY)
/* wait */ ;

The classic problem comes when the compiler loads the value once,
then goes into an infinite loop rather than checking when the flag
comes on repeatedly.

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 switch *DOES* use { }, but it's very, very, very rarely appropriate
to use switch without { }.

You can do the same thing within { } (anywhere, as in after a while)
with labels and goto (although case labels are a little different
from regular labels, they are still labels).

Gordon L. Burditt
Jan 31 '06 #5

Sensei wrote:
On 2006-01-31 17:01:29 +0100, "Vladimir S. Oka" <no****@btopenworld.com> said:

It's probably useless, but not for curiosity...


I don't quite follow your thought here...


Well, questions like this one can be seen as useless. I asked this just
for curiosity, not for any ``higher'' intention... :)


Asking out of curiosity is not useless, as it can lead to increased
knowledge. Knowledge is rarely useless. Carry on wondering...

Cheers

Vladimir

Jan 31 '06 #6
Eric Sosman wrote:
Sensei wrote On 01/31/06 10:01,:
.... snip ...
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.


Since the case labels are exactly that I format switch statements
to show such. i.e.:

switch (character) {
case ' ':
case '\t':
case '\n':
case '\f':
case '\r': process_white_space();
break;

case '.':
case ',':
case ':': process_punctuation();
break;
...
default: ...
} /* switch */

by pulling the labels out to the left margin. I will then indent
other nested switch labels. Similarly I pull goto labels out to
the left. The indentation then shows flow of control properly.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 1 '06 #7

"Sensei" <se******@mac.com> wrote in message
news:43***********************@reader2.news.tin.it ...
Hi again!

I have still curiosity about the reason of some C constructs/keywords...
Last question! This is about the switch statement. The statement seems
to me to be completely different from others. A case does not require any { } to
execute more than one instruction, moreover, a brake[sic, break] must be given to make a single case being executed, otherwise all the following
non-brake[sic] case statements will be executed. Why wasn't the switch like the others with { } and automatic brake[sic]?


The ultimate example of this can be found in "C: A Reference Manual" by
Samuel Harbison and Guy Steele, Tartan Laboratories, 3rd. edition, on page
231:

switch (x)
default:
if (prime(x))
case 2: case 3: case 5: case 7:
process_prime(x);
else
case 4: case 6: case 8: case 9: case 10:
process_composite(x);

The only other situation where I've seen an unstructured switch was to
select between two while's at the end of a do-while loop. Otherwise,
structured programming of switch is the way to go (using {}). I think the
reason behind unstructured elements in C, like 'goto' and 'switch', was to
allow porting of Fortran, which is unstructured, to C.

Rod Pemberton
Feb 1 '06 #8
"Rod Pemberton" <do*******@bitbucket.cmm> writes:
[...]
The ultimate example of this can be found in "C: A Reference Manual" by
Samuel Harbison and Guy Steele, Tartan Laboratories, 3rd. edition, on page
231:

switch (x)
default:
if (prime(x))
case 2: case 3: case 5: case 7:
process_prime(x);
else
case 4: case 6: case 8: case 9: case 10:
process_composite(x);

The only other situation where I've seen an unstructured switch was to
select between two while's at the end of a do-while loop. Otherwise,
structured programming of switch is the way to go (using {}). I think the
reason behind unstructured elements in C, like 'goto' and 'switch', was to


See also Duff's Device, <http://www.c-faq.com/misc/duff.html>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 1 '06 #9

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*******@bitbucket.cmm> writes:
[...]
The ultimate example of this can be found in "C: A Reference Manual" by
Samuel Harbison and Guy Steele, Tartan Laboratories, 3rd. edition, on page 231:

switch (x)
default:
if (prime(x))
case 2: case 3: case 5: case 7:
process_prime(x);
else
case 4: case 6: case 8: case 9: case 10:
process_composite(x);

The only other situation where I've seen an unstructured switch was to
select between two while's at the end of a do-while loop. Otherwise,
structured programming of switch is the way to go (using {}). I think the reason behind unstructured elements in C, like 'goto' and 'switch', was
to
See also Duff's Device, <http://www.c-faq.com/misc/duff.html>.


Cool! I don't recall seeing that one, although I'm sure I read Stroustrup's
book, just not as many times as Harbison's and Steele's, I guess. But on
the web, Tom Duff, regarding his "Duff's Device" said: "(Actually, I have
another revolting way to use switches to implement interrupt driven state
machines but it's too horrid to go into.)" So, we are still missing the
_ULTIMATE_ unstructured switch. :( The worst (or best?) part was I
understood Duff's Device before reading the description. :(
Rod Pemberton

Feb 1 '06 #10
On 2006-02-01, Rod Pemberton <do*******@bitbucket.cmm> wrote:

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*******@bitbucket.cmm> writes:
[...]
> The ultimate example of this can be found in "C: A Reference Manual" by
> Samuel Harbison and Guy Steele, Tartan Laboratories, 3rd. edition, on page > 231:
>
> switch (x)
> default:
> if (prime(x))
> case 2: case 3: case 5: case 7:
> process_prime(x);
> else
> case 4: case 6: case 8: case 9: case 10:
> process_composite(x);
>
> The only other situation where I've seen an unstructured switch was to
> select between two while's at the end of a do-while loop. Otherwise,
> structured programming of switch is the way to go (using {}). I think the > reason behind unstructured elements in C, like 'goto' and 'switch', was

to

See also Duff's Device, <http://www.c-faq.com/misc/duff.html>.


Cool! I don't recall seeing that one, although I'm sure I read Stroustrup's
book, just not as many times as Harbison's and Steele's, I guess. But on
the web, Tom Duff, regarding his "Duff's Device" said: "(Actually, I have
another revolting way to use switches to implement interrupt driven state
machines but it's too horrid to go into.)" So, we are still missing the
_ULTIMATE_ unstructured switch. :( The worst (or best?) part was I
understood Duff's Device before reading the description. :(


Check this out:
http://www.chiark.greenend.org.uk/~s...oroutines.html

Update, 2005-03-07: Tom Duff confirms this in a blog comment. The
"revolting way to use switches to implement interrupt driven state
machines" of which he speaks in his original email is indeed the same
trick as I describe here.
Feb 1 '06 #11

"Jordan Abel" <ra*******@gmail.com> wrote in message
news:sl**********************@random.yi.org...
On 2006-02-01, Rod Pemberton <do*******@bitbucket.cmm> wrote:

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*******@bitbucket.cmm> writes:
[...]
> The ultimate example of this can be found in "C: A Reference Manual" by > Samuel Harbison and Guy Steele, Tartan Laboratories, 3rd. edition, on

page
> 231:
>
> switch (x)
> default:
> if (prime(x))
> case 2: case 3: case 5: case 7:
> process_prime(x);
> else
> case 4: case 6: case 8: case 9: case 10:
> process_composite(x);
>
> The only other situation where I've seen an unstructured switch was to > select between two while's at the end of a do-while loop. Otherwise,
> structured programming of switch is the way to go (using {}). I
think the
> reason behind unstructured elements in C, like 'goto' and 'switch',
was to

See also Duff's Device, <http://www.c-faq.com/misc/duff.html>.


Cool! I don't recall seeing that one, although I'm sure I read Stroustrup's book, just not as many times as Harbison's and Steele's, I guess. But on the web, Tom Duff, regarding his "Duff's Device" said: "(Actually, I have another revolting way to use switches to implement interrupt driven state machines but it's too horrid to go into.)" So, we are still missing the
_ULTIMATE_ unstructured switch. :( The worst (or best?) part was I
understood Duff's Device before reading the description. :(


Check this out:
http://www.chiark.greenend.org.uk/~s...oroutines.html

Update, 2005-03-07: Tom Duff confirms this in a blog comment. The
"revolting way to use switches to implement interrupt driven state
machines" of which he speaks in his original email is indeed the same
trick as I describe here.


Yes! Thank you.

He calls it 'continue and return,' or similar to Pascal's 'with' (I have no
idea what that means). But, it is a nice way to 'ping-pong' between two
communicating/coordinated routines. It essentially allows a single
procedure with one entry point to have as many entry points as needed. Very
cool. Usefulness, questionable... That brings up another unstructured
element of C, besides 'goto' and 'switch', which is 'return'. A truly
structured procedure would only have or allow a single entry point and a
single exit point, i.e., 'return'. Instead , C allows multiple exit points,
via 'return', for procedures but has no multiple entry points by default.

Rod Pemberton
Feb 2 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Web Science | last post by:
Site and Features: http://www.eigensearch.com Search engine, eigenMethod, eigenvector, mathematical, manifolds, science, technical, search tools, eigenmath, Jacobian, quantum, mechanics,...
1
by: Web Science | last post by:
Site and Features: http://www.eigensearch.com Search engine, eigenMethod, eigenvector, mathematical, manifolds, science, technical, search tools, eigenmath, Jacobian, quantum, mechanics,...
22
by: chris | last post by:
I have to retreive data from a old DOS program written in 1995 but I don't recognize the language -- Here's a sample of the code used in the .lib files -- Can anyone tell me what language it is ? ...
193
by: Michael B. | last post by:
I was just thinking about this, specifically wondering if there's any features that the C specification currently lacks, and which may be included in some future standardization. Of course, I...
5
by: masood.iqbal | last post by:
My simplistic mind tells me that having local variables within looping constructs is a bad idea. The reason is that these variables are created during the beginning of an iteration and deleted at...
0
by: Web Science | last post by:
Site and Features: http://www.eigensearch.com Search engine, eigenMethod, eigenvector, mathematical, manifolds, science, technical, search tools, eigenmath, Jacobian, quantum, mechanics,...
0
by: Web Science | last post by:
Site and Features: http://www.eigensearch.com Search engine, eigenMethod, eigenvector, mathematical, manifolds, science, technical, search tools, eigenmath, Jacobian, quantum, mechanics,...
21
by: shotokan99 | last post by:
guys, i read in some forums that php is just for hobbiest, and is not suited for some serius and heavy application. for robust and hi performance application asp.net or jsp is the way to go. how...
26
by: Frank Samuelson | last post by:
I love Python, and it is one of my 2 favorite languages. I would suggest that Python steal some aspects of the S language. ------------------------------------------------------- 1. Currently...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.