Why does C/C++ use const & static so many times?

R

Randy Budd

The one major beef I have with C/C++ is that there are so many variations
for
the same word. For example:

static global variable - variable accessible only from within source
file
static function - function accessible only from within source
file
static variable in function - variable whose value gets retained between
calls
static member variable - variable with one value for all classes
static member function - function accessible from outside the class

Why do they use the same word (static) for these multiple uses, when they
clearly have different effects? Is there some underlying reason why they
are
the same word, or is it the result of the original authors trying to be
clever
and trying to save on new keywords? Why not use a new keyword for each
of the
uses?

The same thing goes for const. Having a const char * variable const is
technically correct and I understand what it means (I think), but
wouldn't it
be more intelligent to use a different keyword when used on the left side
of
a variable than when on the right side? It would definitely make things a
lot clearer.

Does anyone know if there is any historical significance to why they use
the
same words multiple times?

Thanks

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your
Own
 
M

Moi

The one major beef I have with C/C++ is that there are so many
variations for
the same word. For example:

static global variable - variable accessible only from within
source file
static function - function accessible only from within
source file
static variable in function - variable whose value gets retained between
calls
static member variable - variable with one value for all classes
static member function - function accessible from outside the class

Why do they use the same word (static) for these multiple uses, when
they clearly have different effects? Is there some underlying reason
why they are
the same word, or is it the result of the original authors trying to be
clever
and trying to save on new keywords? Why not use a new keyword for each
of the
uses?

Well if it confuses you, you can always use
#define private static

:)

BTW have you also remarked the various purposes for commas and parentheses ?

HTH,
AvK
 
K

Keith Thompson

Randy Budd said:
The one major beef I have with C/C++ is that there are so many
variations for the same word. For example:

static global variable - variable accessible only from within source
file
static function - function accessible only from within source
file
static variable in function - variable whose value gets retained between
calls
static member variable - variable with one value for all classes
static member function - function accessible from outside the class

The latter two are specific to C++, which is a different language than
C. (I'll mention that your descriptions aren't quite accurate.)

Yes, the "static" keyword is fairly heavily overloaded, but the meanings
are related.

An object with "static storage duration" exists for the lifetime of the
program, regardless of its visibility. Applying the keyword "static" to
an object declared inside a function changes its storage duration from
automatic to static. For an object declared outside a function, its
storage duration is already static, so applying "static" changes its
visibility (yes, I suppose this is a bit questionable).

C99 adds at least one more new meaning for "static". As our own Peter
Seebach said, "It wouldn't be a new C standard if it didn't give a new
meaning to the word `static'."
Why do they use the same word (static) for these multiple uses, when
they clearly have different effects? Is there some underlying reason
why they are the same word, or is it the result of the original
authors trying to be clever and trying to save on new keywords? Why
not use a new keyword for each of the uses?

The same thing goes for const. Having a const char * variable const
is technically correct and I understand what it means (I think), but
wouldn't it be more intelligent to use a different keyword when used
on the left side of a variable than when on the right side? It would
definitely make things a lot clearer.

No, I'm reasonably sure that "const char * variable const;" is a syntax
error (at least in C). "const char *const variable;" is legal, but the
"const" keyword means the same thing in both cases; the first means that
the pointed-to char object (if any) is read-only, and the second means
that the pointer object is read-only. How would using two different
keywords help?
Does anyone know if there is any historical significance to why they
use the same words multiple times?

Some of it probably makes more sense than you think it does, and some
of it is probably just historical accident and a desire to miminize
new keywords.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your
Own

Cute.
 
E

Eric Sosman

The one major beef I have with C/C++ is that there are so many variations
for
the same word.

If that's your worst problem with C (I can't speak for C++), you're
either vastly more tolerant or vastly more skilled than I am ...
For example:

static global variable - variable accessible only from within source
file

I guess by "global variable" you mean "variable identifier at file
scope." Since all file-scope variables have static storage duration,
this use of `static' is about linkage (internal rather than external)
rather than about storage duration (which it couldn't affect anyhow).
static function - function accessible only from within source
file

This is really the same as the first one. Since functions have no
storage duration of any kind, again it's only the linkage that we need
to talk about. So `static' applied to a function means the same thing
as when applied to a file-scope variable: "Internal linkage, please."
static variable in function - variable whose value gets retained between
calls

Now we come to C's other main use of `static': To govern storage
duration. A non-extern variable at block scope has no linkage (not even
internal linkage), so there's no need to describe what kind of linkage
it doesn't have; the meaning of `static' at file scope wouldn't apply.
Instead, `static' now specifies "static storage duration" instead of
"automatic storage duration." The retention of value (including for
recursive calls) is a consequence of the storage duration.
static member variable - variable with one value for all classes
static member function - function accessible from outside the class

These are C++ things, of which I wot not.

The C99 Standard introduced a further use for `static', to declare
that a function parameter points to an array of at least thus-and-such
a size:

void func(double pointer[static 10]) { ... }

Although it looks like an array, the parameter is actually a double*
pointer, as has always been the case. The `static 10' declares that
all of pointer[0] through pointer[9] actually exist (further indices
may or may not be valid). This knowledge can allow an optimizer to
do things like speculative pre-fetches.

Why was `static' chosen for this third meaning unrelated to the
first two? Probably because it was available; the Committee didn't
need to invent a new keyword like `atleast' and risk co-opting a
variable name some existing code already used.

It's also been said that "It's not a new C standard without a new
meaning for the keyword static."
Why do they use the same word (static) for these multiple uses, when they
clearly have different effects? Is there some underlying reason why they
are
the same word, or is it the result of the original authors trying to be
clever
and trying to save on new keywords? Why not use a new keyword for each
of the
uses?

Suppose C's three meanings for `static' were given different
keywords, `static' and `intern' and `atleast', say. Obviously, no
pre-existing code uses `static' as an identifier, but given the
large amount of source in existence it's virtually certain that the
other two *do* appear as names, somewhere. By "overloading" an
existing keyword, the Standard refrains from invalidating such code.

True, the Committee has not always been so considerate. If
your K&R source used `void' or `const' as an identifier, you were
out of luck when ANSI/C90 came along. If your C90 code used `inline'
or `restrict' as identifiers, C99 brought unwelcome surprises. (If
your perfectly valid K&R/C90/C99 code uses `class' or `private' as
an identifier, I think you're out of luck if someone decides to dump
it through a C++ compiler; this why I make a point of using `new' as
an identifier whenever it seems descriptive.)
The same thing goes for const. Having a const char * variable const is
technically correct and I understand what it means (I think), but
wouldn't it
be more intelligent to use a different keyword when used on the left side
of
a variable than when on the right side? It would definitely make things a
lot clearer.

An example of actual syntax might clarify your complaint.
Does anyone know if there is any historical significance to why they use
the
same words multiple times?

Dunno <shrug>. It might provide food for thought if you were to
examine the individual words of your final sentence, and see how many
of *those* have multiple meanings depending on context. "Does" might
be a buck's harem; "use" might be a noun (or in spoken language, the
second person plural pronoun as uttered in a bad gangster accent),
and so on. Context clarifies which meanings apply, in C as here.
 
S

sandeep

Eric said:
Suppose C's three meanings for `static' were given different
keywords, `static' and `intern' and `atleast', say. Obviously, no
pre-existing code uses `static' as an identifier, but given the large
amount of source in existence it's virtually certain that the other two
*do* appear as names, somewhere. By "overloading" an existing keyword,
the Standard refrains from invalidating such code.

You need lateral thinking! They could use a reserved name, eg EINTERN or
__atleast.
True, the Committee has not always been so considerate. If
your K&R source used `void' or `const' as an identifier, you were out of
luck when ANSI/C90 came along. If your C90 code used `inline' or
`restrict' as identifiers, C99 brought unwelcome surprises. (If your
perfectly valid K&R/C90/C99 code uses `class' or `private' as an
identifier, I think you're out of luck if someone decides to dump it
through a C++ compiler; this why I make a point of using `new' as an
identifier whenever it seems descriptive.)

Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.
 
K

Keith Thompson

sandeep said:
You need lateral thinking! They could use a reserved name, eg EINTERN or
__atleast.

Yes, that could have been done. _Extern and _Atleast would be more
consistent with certain other new C99 keywords.

But backward compatibility isn't the only criterion. Avoiding jarring
ugliness is another. Almost all C keywords are lowercase; maintaining
some visual consistency is a good thing.
Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.

No, I think he meant exactly what he wrote. By using "new" as an
identifier, he ensures that his C code will not accidentally or
deliberately be compiled with a C++ compiler, and that anyone who
feels a need to translate it to C++ will have to stop and think
about it.
 
E

Ed

Randy Budd said:
The one major beef I have with C/C++ is that there are so many
variations
for
the same word. For example:

static global variable - variable accessible only from within
source
file
static function - function accessible only from within
source
file
static variable in function - variable whose value gets retained
between
calls
static member variable - variable with one value for all classes
static member function - function accessible from outside the
class

Why do they use the same word (static) for these multiple uses, when
they
clearly have different effects? Is there some underlying reason why
they
are
the same word, or is it the result of the original authors trying to be
clever
and trying to save on new keywords? Why not use a new keyword for each
of the
uses?

The same thing goes for const. Having a const char * variable const is
technically correct and I understand what it means (I think), but
wouldn't it
be more intelligent to use a different keyword when used on the left
side
of
a variable than when on the right side? It would definitely make
things a
lot clearer.

Does anyone know if there is any historical significance to why they
use
the
same words multiple times?

It's an example of becoming so entranced by a paradigm that it manifests
itself in something negative. The paradigm is: "more keywords are bad".
They took a quantity thing and hoisted it to commandment level and in
doing so reduced the quality of the language. Paradigms are bad.
Open-minded, reasonable, logical, practical thinking is always
preferable. Finally, the over overloading of keywords may be a good
example of "committee think".
 
P

Pillsy

Since all file-scope variables have static storage duration,
this use of `static' is about linkage (internal rather than external)
rather than about storage duration (which it couldn't affect anyhow).

Why is "static" a good word for describing internal linkage anyway? Or
did they just not want to use up another keyword if they didn't have
to?

Cheers,
Pillsy
 
E

Eric Sosman

Eric said:
[...] (If your
perfectly valid K&R/C90/C99 code uses `class' or `private' as an
identifier, I think you're out of luck if someone decides to dump it
through a C++ compiler; this why I make a point of using `new' as an
identifier whenever it seems descriptive.)

Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.

No, "I meant what I said, and I said what I meant." I don't
want my C code misinterpreted subtly by a C++ compiler, because
I don't know C++ and even my best C probably has "mistakes" from a
C++ point of view. By using `new' (and by not casting void* and
so on), I try to see to it that anyone so foolish as to use the
wrong compiler on my code will at least hear some warning bells.
 
E

Eric Sosman

Why is "static" a good word for describing internal linkage anyway? Or
did they just not want to use up another keyword if they didn't have
to?

It doesn't seem "natural" to me, I've got to admit. The meaning
in connection with storage duration makes sense ("This variable is
statically allocated, that variable is automatically allocated").
A `private' keyword (or still better, a `public' keyword and change
the default linkage to internal) would perhaps have read more smoothly.

But DMR needed a keyword to denote internal linkage, and he
chose to recycle `static' for the purpose -- maybe it seemed appealing,
maybe he was following established practice from B or BCPL, I don't
know. He chose `static'; let us be glad he didn't choose `else'.
 
R

robertwessel2

It's an example of becoming so entranced by a paradigm that it manifests
itself in something negative. The paradigm is: "more keywords are bad".
They took a quantity thing and hoisted it to commandment level and in
doing so reduced the quality of the language. Paradigms are bad.
Open-minded, reasonable, logical, practical thinking is always
preferable. Finally, the over overloading of keywords may be a good
example of "committee think".


Well, not wanting to break existing code is not a bad goal - and
adding keywords will break existing code, so adding keywords should,
at least, not be done on whim.

There can also be strong objections from the user community. The
Cobol85 standard was held up for years by a large and vocal minority
of the user community that objected to minor incompatibilities in the
new standard, the most prominent being the introduction of a large
number of new keywords. The final unhappy compromise introduced a
requirement for a method (usually something like a pragma) for
undefining language keywords. I'm sure any language standard
committee member would be almost desperate to avoid a repeat of that.
 
N

Nobody

It's an example of becoming so entranced by a paradigm that it manifests
itself in something negative. The paradigm is: "more keywords are bad".

The irony is that, in practically the same breath, C added the completely
pointless "auto" keyword.
 
K

Keith Thompson

Nobody said:
The irony is that, in practically the same breath, C added the completely
pointless "auto" keyword.

The "auto" keyword is very old, going back to B and/or BCPL, and it
wasn't pointless back then. It was legal and very common to rely on the
"implicit int" rule, and the "auto" keyword was a way to mark something
as an object declaration without specifying the type:

{
auto x;
static y;
/* ... */
}

I agree that it's largely pointless in modern C. (BTW, C++ is in
the process of re-using it for a new purpose; "auto x = expr_value;"
declares x as on object of the type of expr.)
 
N

Nick Keighley

The one major beef I have with C/C++ is that there are so many variations
for the same word.  

seems a pretty weird thing to have a "major beef" with. It was the
curly brackets that got me. That and using ";" as a statement
terminator rather a separator.
For example:

static global variable      - variable accessible only from within source
file

The C standard has no mention of "global variables". There are at
least two reasonable definitions. If you're going to criticise C at
least criticise it for things it does rather than things you think it
does.
static function             - function accessible only from within source
file

that's the same as your first definition
static variable in function - variable whose value gets retained between
calls

I agree, this has always seemed odd to me.
static member variable      - variable with one value for all classes
static member function      - function accessible from outside the class

those are C++ things not C things.
Why do they use the same word (static) for these multiple uses, when they
clearly have different effects?  Is there some underlying reason why they
are the same word, or is it the result of the original authors trying to be
clever and trying to save on new keywords?  

I think they were saving on keywords. I'm not entirely sure why (but
see other posts in this thread for ideas)

The same thing goes for const.  Having a const char * variable const is
technically correct and I understand what it means (I think),

is it correct? What /does/ it mean?
but wouldn't it be more intelligent to use a different keyword when used
on the left side of a variable than when on the right side?  It would
definitely make things a lot clearer.

since I didn't know you *could* use const on the right hand side of a
variable it wouldn't make things any clearer to me.
Does anyone know if there is any historical significance to why they use
the same words multiple times?

don't think so



--

"If you think C++ is not overly complicated, just what is a protected
abstract virtual base pure virtual private destructor, and when
was the last time you needed one?"
-- Tom Cargil, C++ Journal.
 
S

sandeep

Eric said:
Eric said:
[...] (If your
perfectly valid K&R/C90/C99 code uses `class' or `private' as an
identifier, I think you're out of luck if someone decides to dump it
through a C++ compiler; this why I make a point of using `new' as an
identifier whenever it seems descriptive.)

Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.

No, "I meant what I said, and I said what I meant." I don't
want my C code misinterpreted subtly by a C++ compiler, because I don't
know C++ and even my best C probably has "mistakes" from a C++ point of
view. By using `new' (and by not casting void* and so on), I try to see
to it that anyone so foolish as to use the wrong compiler on my code
will at least hear some warning bells.

But this is crazy!!

Why would you introduce non-portable constructions deliberately? I can
understand if there's some feature of C you need that clashes with C++
then use it, but why go out of your way to make your code non-portable to
C++ compilers?

Compatibility with C++ (if a few keywords etc are avoided) is one of the
great strengths of C...
 
E

Eric Sosman

Eric said:
Eric Sosman writes:
[...] (If your
perfectly valid K&R/C90/C99 code uses `class' or `private' as an
identifier, I think you're out of luck if someone decides to dump it
through a C++ compiler; this why I make a point of using `new' as an
identifier whenever it seems descriptive.)

Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.

No, "I meant what I said, and I said what I meant." I don't
want my C code misinterpreted subtly by a C++ compiler, because I don't
know C++ and even my best C probably has "mistakes" from a C++ point of
view. By using `new' (and by not casting void* and so on), I try to see
to it that anyone so foolish as to use the wrong compiler on my code
will at least hear some warning bells.

But this is crazy!!

Why would you introduce non-portable constructions deliberately? I can
understand if there's some feature of C you need that clashes with C++
then use it, but why go out of your way to make your code non-portable to
C++ compilers?

It may come as a surprise to you, but I also use Algol keywords
in my C code, and deliberately write in a style no PL/1 compiler
will accept.

To the limits of my ability, my C code is correct as C: It does
what it's supposed to do. That doesn't mean it would be correct if
processed by a compiler for Fortran, or Pascal, or LISP, C++, Basic,
XPL, TAL, or any other language: It's C, not something else. Now,
no one in his right mind would try to push C code through a CUPL
compiler, or SNOBOL through a C compiler, but there seems to be a
goodly number of people who will try to push C code through a C++
compiler. If a C++ compiler happens to accept my C code (changing
its meaning silently and subtly), my mis-translated code may then do
something undesirable or at least peculiar. Know what happens next?
*I* get blamed for *their* use of the wrong compiler, because it's
my "incorrect" code that misbehaves.

No,

Thank

You.

If somebody intentionally pushes my C code through a C++ compiler,
he's a nitwit and deserves the error messages he'll get. If it happens
accidentally (sloppy Makefile rule, say), he'll be glad of being alerted
to the mistake before it causes deeper trouble.

Here's a factoid, Sandeep: "Gift" is a noun in both English
and German, albeit with somewhat different meanings. Suppose a
person accosts you in the street, hands you a glass of unkonwn fluid,
and speaks the single word "Gift" with no indication of what language
he's using. Will you drink?

The fact that two different languages share a few words does not
mean that the languages are interchangeable, nor even compatible.
Even when they share a great number of words and constructs due to a
common ancestry, they're not interchangeable nor compatible (try
speaking Spanish next time you're in Napoli).
Compatibility with C++ (if a few keywords etc are avoided) is one of the
great strengths of C...

Ah! At last, I understand why C never amounted to anything until
C++ came along.
 
K

Keith Thompson

sandeep said:
Eric said:
Eric Sosman writes:
[...] (If your
perfectly valid K&R/C90/C99 code uses `class' or `private' as an
identifier, I think you're out of luck if someone decides to dump it
through a C++ compiler; this why I make a point of using `new' as an
identifier whenever it seems descriptive.)

Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.

No, "I meant what I said, and I said what I meant." I don't
want my C code misinterpreted subtly by a C++ compiler, because I don't
know C++ and even my best C probably has "mistakes" from a C++ point of
view. By using `new' (and by not casting void* and so on), I try to see
to it that anyone so foolish as to use the wrong compiler on my code
will at least hear some warning bells.

But this is crazy!!

Why would you introduce non-portable constructions deliberately? I can
understand if there's some feature of C you need that clashes with C++
then use it, but why go out of your way to make your code non-portable to
C++ compilers?

He just explained his reasons. Did you not understand them, or do
you disagree with them? If you disagree, how was he wrong?

C and C++ are two different languages. Some of the differences
between them are quite subtle; there are cases of code that's valid
C and valid C++, but with different behavior. Eric doesn't know C++
well enough to reliably avoid those subtle differences.

And the difference between *good* C and *good* C++ (malloc vs. new,
etc.) is much wider than the difference between *valid* C and
*valid* C++.

Anyone who wants to compile his code just needs to use a C compiler.
Is that such a heavy burden?
Compatibility with C++ (if a few keywords etc are avoided) is one of the
great strengths of C...

I'd say it's a strength of C++.

In most circumstances, there's no good reason to let C's incomplete
upward compatibility with C++ affect the way one writes C code.
(There are a few notable exceptions.) Maintaining code compatibility
is possible, but it requires extra work; in Eric's case, there's
no benefit.
 
S

sandeep

Keith said:
sandeep said:
Eric said:
On 6/23/2010 3:13 PM, sandeep wrote:
Eric Sosman writes:
[...] (If your
perfectly valid K&R/C90/C99 code uses `class' or `private' as an
identifier, I think you're out of luck if someone decides to dump it
through a C++ compiler; this why I make a point of using `new' as an
identifier whenever it seems descriptive.)

Uhhh I think you mean of NOT using new, so that your code will be
portable to C++ compilers too.

No, "I meant what I said, and I said what I meant." I don't
want my C code misinterpreted subtly by a C++ compiler, because I
don't know C++ and even my best C probably has "mistakes" from a C++
point of view. By using `new' (and by not casting void* and so on), I
try to see to it that anyone so foolish as to use the wrong compiler
on my code will at least hear some warning bells.

But this is crazy!!

Why would you introduce non-portable constructions deliberately? I can
understand if there's some feature of C you need that clashes with C++
then use it, but why go out of your way to make your code non-portable
to C++ compilers?

He just explained his reasons. Did you not understand them, or do you
disagree with them? If you disagree, how was he wrong?

I disagree with Mr Sosman on this point.

In my opinion portability is a crucial feature of code. Time and time
again we see good code becoming obsoleted because it was written in a non-
portable way and hardware moves on. Sometimes non-portability is needed,
for example a network program will either use BSD sockets or WinSock and
so incompatability is forced. But in my opinion it is ONLY worth giving
up portability in order to get access to a useful platform-specific
feature.

Deliberately making code non-portable to C++ compilers for no clear
advantage is crazy! Many people choose to compile C with C++ compilers...
why make life difficult for them?
C and C++ are two different languages. Some of the differences between
them are quite subtle; there are cases of code that's valid C and valid
C++, but with different behavior. Eric doesn't know C++ well enough to
reliably avoid those subtle differences.

For sure Mr Sosman knows C++ well enough! All that is needed is avoiding
certain artificial constructions that don't occur in normal code.
And the difference between *good* C and *good* C++ (malloc vs. new,
etc.) is much wider than the difference between *valid* C and *valid*
C++.

Anyone who wants to compile his code just needs to use a C compiler. Is
that such a heavy burden?

It is a very heavy burden for someone with a C++ compiler at hand but no
C compiler!
 
E

Eric Sosman

I disagree with Mr Sosman on this point.

In my opinion portability is a crucial feature of code. Time and time
again we see good code becoming obsoleted because it was written in a non-
portable way and hardware moves on. Sometimes non-portability is needed,
for example a network program will either use BSD sockets or WinSock and
so incompatability is forced. But in my opinion it is ONLY worth giving
up portability in order to get access to a useful platform-specific
feature.

What's non-portable about writing portable C?

It seems to me you're trying to say that code isn't portable
unless it means the same thing not only in multiple environments, but
in multiple languages as well. Such polyglot constructs are sometimes
possible: I recall seeing a source fragment that output "Hello, world!"
in all three of Fortran, C, and csh, and there's the startling example
of "Mots D'Heures: Gousses, Rames." But these are oddities, exercises
in cleverness whose purpose is to amuse.
Deliberately making code non-portable to C++ compilers for no clear
advantage is crazy! Many people choose to compile C with C++ compilers...
why make life difficult for them?

They're making their own lives difficult by using the wrong
compiler. If I make a nail and someone tries to hammer it home with
a hacksaw, who's responsible for the difficulty?
For sure Mr Sosman knows C++ well enough! All that is needed is avoiding
certain artificial constructions that don't occur in normal code.

I am not now, never have been, and do not intend to become a
member of the C++ Party.
It is a very heavy burden for someone with a C++ compiler at hand but no
C compiler!

Tough on them. I make nails; I'm not going to try to redesign
them for people who can't be bothered to get hammers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,114
Members
46,702
Latest member
VernitaGow

Latest Threads

Top