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

K

Keith Thompson

sandeep said:
Keith said:
sandeep said:
Eric Sosman writes:
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?

You might want to stop using the word "crazy" when talking to people who
know this stuff better than you do.

There is a clear advantage. It encourages users of his code to
compile it with a C compiler. Such code is portable to any system
with a C compiler.
For sure Mr Sosman knows C++ well enough! All that is needed is avoiding
certain artificial constructions that don't occur in normal code.

Eric says he doesn't know C++; do you have some reason to doubt
his word? The differences beween the C and the C-like subset of C++
are subtle. He chooses, quite reasonably, not to expend the effort
to keep track of those differences when he's writing C.

Can you list, off the top of your head, all the C++ keywords that
are legal identifiers in C? As of the 1998 or 2003 C++ standard,
there are 30 of them; as of the N2315 C++ draft, there are 33.
Can you use "long long" in C++? The answer depends on which version
of the standard your C++ compiler conforms to. What about the
"restrict" keyword?

Did you know that the syntax of the conditional operator differs
between C and C++? Do you know how it differs? Do you know how
that difference affects code? (I don't know the answer to that
last one myself, but I could figure it out.)

The C++ standard includes the most of the C standard library
by reference -- but which version, C90 or C99 (or C95 for that
matter)? Which version does the C++ compiler you're using support?
Which version is supported by the C++ compiler used by someone
you've never met who wants to compile your code three years from now?

I program in C++ for a living, and I'm not certain that I can write
C++-compatible C code with 100% reliability. I probably could if
I put some effort into it (including doing complete testing with
both C and C++ compilers), but it's just not worth it unless I have
a specific requirement to write cross-language compatible code.

If somebody else wants to take my or Eric's C code and turn it into
C++ code, they're welcome to do so, assuming the code is released
under some appropriate license. But it could be a non-trivial task.
Using "new" as an identifier doesn't make it significantly more
difficult, it just acts as a reminder.
It is a very heavy burden for someone with a C++ compiler at hand but no
C compiler!

Like who?

Most C++ compilers are also C compilers (or include C front-ends
in the same package); gcc is a prominent example, but certainly
not the only one.

Most compiler suites that handle both C and C++ will automatically
treat a file whose name ends in ".c" as C code.

If you want to compile C code, you need to get a C compiler.

The existence of a language that happens to be a near superset
of C does not impose any obligation on C programmers to write
code that's compatible with that language. Would you be upset
if I wrote C code that's deliberately imcompatible with Objective-C
(I'm not sure that's even possible)? Or with D?

Or do you advocate getting rid of the C language altogether, and
instead defining a restricted subset of C++? Isn't that the logical
conclusion of your argument?
 
E

Ed

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.

If someone writes to C90 and C99 introduced new keywords and they don't
want to change or examine their code, let them stick with C90. No on is
forcing anyone to use the new standard. Right? With the process you gave
above, the language gets worse and worse unnecessarily.
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 users are unduly influencing evolution of a language when they should
simply realize that they can keep using the compilers they have. If it's
a compiler/IDE technology issue (the want the latest and greatest
development environment), then they should take it up with their vendor,
for example, to keep supporting C9X or whatever for them.
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.

I find extremely weak, the argument that existing keywords should be
uintuitively overloaded rather than introducing the appropriate new one
because someone somewhere may have named a variable the proposed new
keyword.
 
P

Peter Nilsson

He's not introducting non-portable constructions. They are generally
very portable to other C compilers. That they are not portable to
entirely other languages is not always a priority.

Indeed, it takes a great deal of skill to master two languages and
produce programs that work _the same way_ under both.

The question is: why go out of your way to make C program portable
to C++? There are reasons, but the important thing to note is
that you do have to go out of your way.

Not really. Eric simply stated what he does, and to some extent
acknowledged that it was inconsiderate [as the C Committees
have been inconsiderate of past programs broken by name clashes.]

I'm not sure anyone can be truly right or wrong on a style issue.
They simply have a preference which either works well to some
degree for them or it doesn't. Different techniques can work
very well for different people. That doesn't mean either can
claim to be strictly right or wrong.
I disagree with Mr Sosman on this point.

In my opinion portability is a crucial feature of code.

Portability to what? People who compile C programs under C++
generally do so not for portability reasons, but for stricter
compiler rules and a measure of robustness and error detection
that brings. Of course, it comes at a cost too.
Time and time again we see good code becoming obsoleted
because it was written in a non-portable way and hardware
moves on.

What does that have to do with writing C code compatible with
C++?
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.

Same question.
Deliberately making code non-portable to C++ compilers

.... i.e. another language ...
for no clear advantage is crazy!

What is the clear loss?
Many people choose to compile C with C++ compilers...

True, but I'd guess about 99% have no real idea why beyond:
that's the way many other people do it.
why make life difficult for them?

Why make it easy for them? Especially if most are ignorant
of the additional complexities and subtleties of bringing
code up to complience for two languages that have differing
paradigms?
For sure Mr Sosman knows C++ well enough!

Does he? Does he _have_ to?
All that is needed is avoiding certain artificial
constructions that don't occur in normal code.

<type> <identifier>; /* declaration */

How is that an artificial construct?

I support people who make their code compilable to both C
and C++. I'm irked by people that don't who criticise that
technique as foolish. But I'm equally irked by people who
reverse the criticism.

Personally, I think it's important to know, or at least
understand and appreciate, a number of techniques. Especially
if you're maintaining a lot of code written by other people.
But there is no ONE TRUE STYLE.
 
D

Dann Corbit

[snip]
Perhaps, but (a) it's a C program written for C rules, not C++ rules, so
a C compiler is indicated, and if you haven't got one the right response
is to get one; and (b) it is actually quite rare for someone with a C++
compiler to be without a C compiler - so rare, in fact, that I don't
think I've ever encountered such a person.

I'd like to introduce myself, then. ;-)

On one of our hardware platforms we have a C++ compiler but no C
compiler.

From time to time, it is a pain in the backside.

As far as portability goes -- if we see a need in the code we write to
be portable across even languages then we may write code designed for
that.

For instance, if I want my C code to compile with a C++ compiler, I will
not use 'new' as a variable name because it is an operator in C++. That
having been said, if someone does not care about C++ portability of C
code then I don't see why they should bother with the extra effort.
After all, if we don't actually test this desired capability then our
goal has little value and if we do test then it is an added expense.

The PostgreSQL code base uses 'new' a lot for variable names. Yet it is
still wonderful and useful code.

I think it is a mistake to try to inflict our wishes for this sort of
thing on other people.

In a similar vein, if you are writing code for a DSP on some non-hosted
toaster CPU -- all the while reading and writing hardware ports and
other naughty non-portable things, then I see little point in trying to
make your code totally general unless it has some value for *you*.

Portability adds the following value:
If I want to use the code I wrote somewhere else, it is likely to work.
If I never want to use the code somewhere else, then it's up to me to
write portable code or not.

I tend to try to write code that is portable. I tend to try not to use
C++ keywords like new, delete, protected, public, private, etc. when I
write C code because someday I might want to reuse the code in a C++
class. If Joe Schmedlap does not have the same goal with his code, why
should he bother trying for maximal portability when it has a real cost
to do so?

IMO-YMMV
 
K

Kenny McCormack

pete said:
"Portability" doesn't mean that a C program
should also be a program in a different language.

The game here is, of course, to pretend like C++ is as much a different
language versus C as is, say, COBOL versus C. While true in the
obscure, black/white universe of CLC regs, no sensible person believes
this. But that won't stop the regs from troll, troll, trolling the
night away...
It is common for a C++ compiler
to become a C compiler when compiling *.c files.

But not universal. Similar to what another poster recently noted, I
myself am familiar with a real-life business-world situation where,
because of, shall we say, a purchasing error, they ended up compiling
all of their C code with a C++ (only!) compiler (for several years, in
fact), and they never knew it was happening until I figured it out and
pointed it out to them.
 
T

TonyMc

sandeep said:
But this is crazy!!

Sandeep, as an occasional poster here, but someone who has learned so
much C from the experts who post here regularly, I think the correct
response here would have been something like "Ah, sorry, I misunderstood
the point you were making. I'm going to have to think about that."
That way you will definitely get to be a better C programmer. Maybe
even a better C++ programmer too, though that would be a side-effect.
Why not try it and see how it goes?

Tony
 
E

Eric Sosman

Dann said:
[...]
On one of our hardware platforms we have a C++ compiler but no C
compiler.

From time to time, it is a pain in the backside.

Easy fix: write a C compiler for that platform.

In The Beginning, IIRC, C++ source was translated to C and a
C compiler took things from there. Given a C++ compiler and no
C compiler, the obvious approach is to write a source-to-source
translator that goes the other way, taking C source to C++ source
that the existing C++ compiler can handle.

The translator from C++ to C was named "cfront," so the reverse
translator should be "cback," pronounced "Seebach."
 
S

Sebastian

Did you know that the syntax of the conditional operator differs
between C and C++?  Do you know how it differs?  Do you know how
that difference affects code?  (I don't know the answer to that
last one myself, but I could figure it out.)

Out of curiosity, please explain. I was under the impression that C++
just extended ?: with a couple of rules w.r.t. references, class
hierarchies and conversion operators. Are you implying that there
exists a ?: example written in C that won't do the same as the
corresponding ?: expression in C++?

Cheers!
SG
 
L

lawrence.jones

Eric Sosman said:
The translator from C++ to C was named "cfront," so the reverse
translator should be "cback," pronounced "Seebach."

No, it's pronounced "Seebs", much like WATFIV is officially pronounced
"watt four". :)
 
K

Kenny McCormack

Sandeep, as an occasional poster here, but someone who has learned so
much C from the experts who post here regularly, I think the correct
response here would have been something like "Ah, sorry, I misunderstood
the point you were making. I'm going to have to think about that."
That way you will definitely get to be a better C programmer. Maybe
even a better C++ programmer too, though that would be a side-effect.
Why not try it and see how it goes?

Could you, possibly, get your face crammed any further up Kiki's and
Eric's butts?
 
K

Keith Thompson

Sebastian said:
Out of curiosity, please explain. I was under the impression that C++
just extended ?: with a couple of rules w.r.t. references, class
hierarchies and conversion operators. Are you implying that there
exists a ?: example written in C that won't do the same as the
corresponding ?: expression in C++?

In C, the syntax for the conditional operator is:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression

In C++, it's:

conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression

I haven't taken the time to work out the implications.
 
S

sandeep

Keith said:
Eric says he doesn't know C++; do you have some reason to doubt his
word? The differences beween the C and the C-like subset of C++ are
subtle. He chooses, quite reasonably, not to expend the effort to keep
track of those differences when he's writing C.

In my eyes Mr Sosman is a guru. I don't say that he is lying - he is just
a modest man. Everyone with a CS degree from the last 20 years will know
the basics of C++, for sure Mr Sosman is well ahead of that!
Can you list, off the top of your head, all the C++ keywords that are
legal identifiers in C? As of the 1998 or 2003 C++ standard, there are
30 of them; as of the N2315 C++ draft, there are 33. Can you use "long
long" in C++? The answer depends on which version of the standard your
C++ compiler conforms to. What about the "restrict" keyword?

Did you know that the syntax of the conditional operator differs between
C and C++? Do you know how it differs? Do you know how that difference
affects code? (I don't know the answer to that last one myself, but I
could figure it out.)

The C++ standard includes the most of the C standard library by
reference -- but which version, C90 or C99 (or C95 for that matter)?
Which version does the C++ compiler you're using support? Which version
is supported by the C++ compiler used by someone you've never met who
wants to compile your code three years from now?

I am not saying that you should try especially to write C code that is
also valid in C++. What I am saying is that you should not try especially
to write C code that is invalid C++.

Here is an analogy, imagine you are driving along a road. Ahead of you is
a crossroads with a car waiting to turn into your road ahead of you, but
you have priority. If you are very close to the junction then you
exercise your priority and that is fine - this is like using a non-C++
compatible feature if you need it.

But if you are a long way from the junction and the other car would have
plenty of time to turn in front of you, then trying to insist on your
priority by accelerating, sounding your horn and flashing your headlights
to try to intimidate the other driver would be crazy.
 
E

Eric Sosman

In my eyes Mr Sosman is a guru. I don't say that he is lying - he is just
a modest man. Everyone with a CS degree from the last 20 years will know
the basics of C++, for sure Mr Sosman is well ahead of that!

My degree is not in computer science but in mathematics. (Nor
was it earned in the last twenty years ...) Please take my statement
at face value: I do *not* know C++, and have made no effort to learn
it. Perhaps some day I will, but that day has not dawned.
I am not saying that you should try especially to write C code that is
also valid in C++. What I am saying is that you should not try especially
to write C code that is invalid C++.

Since I don't know how to write valid C++, I don't know how to
write valid "common subset of C and C++" code. It is quite possible
that some of my C could get through a C++ compiler without eliciting
complaints, but would have a different meaning when read as C (just
like the "Gift" situation I mentioned a day or so ago). That is, my
perfectly good (God willing) C code might be perfectly bad C++ code,
even if both compilers accept it.

To guard against this error, I try to arrange things so that my
code *will* provoke complaints if mistakenly compiled as C++. A
trivial matter like using `new' as an identifier is not a serious
obstacle; even a relatively stupid editor can overcome it with a few
keystrokes. But stroking those keys will draw someone's attention to
the code, and perhaps make him realize that it hasn't been written
with C++ in mind -- something I couldn't do if I tried, because (as
you seem to have trouble believing) I don't know C++.

Truth to tell, I think using `new' as an identifier will be the
least of a would-be C++ transliterator's problems. A lot of my
"utility" code (ADT's and so on) deals in void* pointers, and I don't
write casts to and from them. Someone who wants to compile my ADT-
using code as C++ will need to insert a lot of casts -- and somewhere
along the line he'll perhaps think "Why not scrap this stuff and use
the STL instead?" And *that* way lies a better hope of success.

A better hope, certainly, than trusting in the C++ skills of
someone who doesn't know the language.
 
L

lawrence.jones

Keith Thompson said:
In C, the syntax for the conditional operator is:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression

In C++, it's:

conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression

I haven't taken the time to work out the implications.

In C,

a ? b = c : d = e

is parsed as:

(a ? (b = c) : d) = e

(which is not valid) whereas in C++ it's parsed as:

a ? (b = c) : (d = e)

Offhand, I can't think of an expression that would be valid in both
languages but do different things, but maybe someone else can.
 
N

Nobody

In C, the syntax for the conditional operator is:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression

In C++, it's:

conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression

I haven't taken the time to work out the implications.

Consider:

a ? b : c = d

In C++, this should parse as:

a ? b : (c = d)

In C, it's invalid; you have to place parentheses around the assignment to
turn it into a primary-expr.

However gcc allows conditionals to be used as lvalues, and parses it
as:

(a ? b : c) = d

with semantics equivalent to:

*(a ? &b : &c) = d

This extension contradicts the standard rules for assignment-expr, which
require a unary-expr to the left of the "=".

Recent versions of gcc complain with:

warning: use of conditional expressions as lvalues is deprecated

I don't think there's an example which is valid in both (standard) C and
C++ but which parses differently (due to the different rules for ?:).
 
M

Moi

[snip]
Perhaps, but (a) it's a C program written for C rules, not C++ rules,
so a C compiler is indicated, and if you haven't got one the right
response is to get one; and (b) it is actually quite rare for someone
with a C++ compiler to be without a C compiler - so rare, in fact, that
I don't think I've ever encountered such a person.

[snip]
The PostgreSQL code base uses 'new' a lot for variable names. Yet it is
still wonderful and useful code.

They do have nice code, but there is still the obsessive typedeffing and casting of
malloc() et.al. ,which suggest they want the code to be accepted by a C++ compiler:

************************************************************/

typedef struct
{
Node *clause;
Cost cost;
} QualItem;

QualItem *items;

items = (QualItem *) palloc(nitems * sizeof(QualItem));

/*****************************************************
, which most of the c.l.c folks would probably express
as ...
*****************************************************/

struct {
struct node *clause;
Cost cost;
} *items;

items = palloc(nitem * sizeof *items);

/**************

The "typedef+cast malloc()" idiom/style is used consistently in all of the Postgres source.

AvK
 
T

Tim Rentsch

Could you, possibly, get your face crammed any further up Kiki's and
Eric's butts?

And if he could, could he then go on to reach the standard
set by some other posters with the respective parts of
their own anatomy?
 
K

Kenny McCormack

Tim Rentsch said:
other reach then the if by own could posters to of the go respective he
some anatomy? he with And set standard on their parts could,

Yup. As I suspected. It makes just as much sense that way as before.
 
N

Nick Keighley

My guess is that he is really thinking of a C++ member function declaration
like:
        const char *fcn() const;

but he was referring to variables, so even in C++ what he said made no
sense
In that case it would be a function that returns a const char * and does
not change the object itself (ie, the "this pointer" is of type
"const Class *" instead of "Class *").

It turns out that there is another C++ keyword "mutable" which means that
you really can change some properties of a class, even if you have a const
pointer to it..  Go figure..  The subject does say "C/C++", so some mention
of C++ is fair by the subject, if not by the newsgroup...


but he got his c++ wrong as well...
 

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

Forum statistics

Threads
474,083
Messages
2,570,589
Members
47,211
Latest member
JaydenBail

Latest Threads

Top