C program is standard C++ program?

K

Keith Thompson

Martin Ambuhl said:
This is an example of why one should *not* cite Stroustrup as an
authority on this issue. He is obviously an authority on C++, but the
fact is that well-written C programs tend to be uncompilable as
C++. Best C practice is often illegal in C++. Remember that BS has a
horse in this race.

The obvious exception to Stroustrup's statement is casting the result
of malloc() (and realloc()). A well-written C program is likely to
call malloc() and assign the result, without a cast, to a pointer
object of a type other than void*; this is illegal in C++.

Are there other significant exceptions? Let's limit the discussion to
well-written C90 programs.

For example, C++ has several additional keywords, but most C programs
aren't going to happen to use them as identifiers; they provide a
counterexample to any claim that C is a strict subset of C++, but not
to Stroustrup's statement.

Character literals are of type char in C++ and of type int in C, but
I've never seen any programs that depend on this difference other than
ones specifically written to demonstrate it.

So, did you have anything in mind other than casting malloc() that
would cause a typical well-written C program not to be valid C++?
 
K

Keith Thompson

Branimir Maksimovic said:
This can be dangerous. restrict type qualifier has specific meaning to C
compiler,
and does not mean anything to C++ compiler, so C++ calling C function with
such parameter can lead to undefined behavior,
therefore it is better to live that as it is.

C99 6.7.3p7 says:

An object that is accessed through a restrict-qualified pointer
has a special association with that pointer. This association,
defined in 6.7.3.1 below, requires that all accesses to that
object use, directly or indirectly, the value of that particular
pointer. The intended use of the restrict qualifier (like the
register storage class) is to promote optimization, and deleting
all instances of the qualifier from all preprocessing translation
units composing a conforming program does not change its meaning
(i.e., observable behavior).

Though I suppose there might be problems if "restrict" is removed from
the caller but not from the implementation of the function.
 
C

Chris Torek

Keith Thompson said:
Are there other significant exceptions? Let's limit the discussion to
well-written C90 programs. [snippage]
So, did you have anything in mind other than casting malloc() that
would cause a typical well-written C program not to be valid C++?

One might argue whether this is "well-written", but I have had
C vs C++ scope issues bite, in real C code that someone attempted
to include part of in a C++ program.

The example I like to use is:

% cat t.c
#include <stdio.h>

struct A { int x[1]; };

int main(void) {
struct B { struct A { int x[1000]; } b; } var;

printf("sizeof(struct A) = %lu\n",
(unsigned long)sizeof(struct A));
return 0;
}
% ln t.c t.c++
% cc -o t t.c
% ./t
sizeof(struct A) = 4000
% cc -o t t.c++
% ./t
sizeof(struct A) = 4
%

This is not the same as the original example (which was of course
much more complicated), but it does demonstrate that C and C++ are
wildly different languages. :)

(OK, one might also argue that it is not "typical" either. It is
true that collisions on structure names are relatively rare, and
it is probably even more rare to have them matter in this way.)
 
B

Branimir Maksimovic

Keith Thompson said:
C99 6.7.3p7 says:

An object that is accessed through a restrict-qualified pointer
has a special association with that pointer. This association,
defined in 6.7.3.1 below, requires that all accesses to that
object use, directly or indirectly, the value of that particular
pointer. The intended use of the restrict qualifier (like the
register storage class) is to promote optimization, and deleting
all instances of the qualifier from all preprocessing translation
units composing a conforming program does not change its meaning
(i.e., observable behavior).

Though I suppose there might be problems if "restrict" is removed from
the caller but not from the implementation of the function.

For the sake of compatibility and good behavior of code it would
be better to remove "restrict" from all C standard library functions.

Greetings, Bane.
 
M

Martin Ambuhl

Branimir said:
For the sake of compatibility and good behavior of code it would
be better to remove "restrict" from all C standard library functions.

For the sake of compatibility and good behavior of code it would
be better to insist that C++ incorporate "restrict" and use it for all
C++ standard library functions where it is appropriate. But C++
chauvinists who believe in bloated languages and obfuscated code will
differ.
 
B

Branimir Maksimovic

Martin Ambuhl said:
For the sake of compatibility and good behavior of code it would
be better to insist that C++ incorporate "restrict" and use it for all
C++ standard library functions where it is appropriate. But C++
chauvinists who believe in bloated languages and obfuscated code will
differ.

Agreed!

Greetings, Bane.
 
N

Nils Weller

[...]
For example, C++ has several additional keywords, but most C programs
aren't going to happen to use them as identifiers; [...]

That reminds me of the Unix functions mktemp()/mkstemp(), which take a
template string argument from which they build a unique file name. Most
Unix manual pages, as well as the POSIX/UNIX standards themselves (which
are ignorant of C++), call the prototypes parameter declaration
``template'' (a C++ keyword):

int mkstemp(char *template);

.... which may be the reason why I've run into problems by calling the
character array I passed to mkstemp() ``template'' in C++ code as well
:)

``new'' and ``class'' are also identifiers I would expect to see in many
C programs written by people unaware of C++ (or by c.l.c. citizens who
use them deliberately to introduce incompatibilities because they
dislike the whole compatibility debate so much), but I agree that it's a
minor problem when porting C programs to C++.
 
T

Tim Prince

Martin said:
For the sake of compatibility and good behavior of code it would
be better to insist that C++ incorporate "restrict" and use it for all
C++ standard library functions where it is appropriate. But C++
chauvinists who believe in bloated languages and obfuscated code will
differ.
Several of the more popular implementations of C++ do implement a form
of restrict as an extension, in a different way for each compiler. I
fail to see, though, how this solves the bloat and obfuscation problem.
 
M

Michael Mair

Keith said:
Michael Mair said:
John Carson wrote:
[...]
The statement that "C++ ... with few exceptions retains C as a
subset" is not a statement of intent but a description of the
relationship between the two languages, albeit one that seems to be
directed at C89. I quote again: "With minor exceptions, C++ is a
superset of C. Most differences stem from C++'s greater emphasis on
type checking. Well-written C programs tend to be C++ programs as
well."
Bjarne Stroustrup, The C++ Programming Language, 3rd ed., Appendix B,
Compatibility, p. 816.

Hmmm, my C code tends to look quite different from my C++ code.
Things I find quite acceptable in C are not acceptable in C++
where better solutions to address certain problems exist.

Apart from the different semantics of void* and ambiguities w.r.t.
overloaded functions, there are better ways to perform explicit
type conversions in C++ than the good old C-style cast.

Stroustrup's statement is that well-written C programs tend to be C++
programs, not that well-written C programs tend to be *well-written*
C++ programs.

The former statement is basically true apart from the issue of casting
the result of malloc(). The latter is not.

I see. Thanks for the pointer (no pun intended).


Cheers
Michael
 
M

Michael Wojcik

"C++ was developed from the C programming language and, with few exceptions,
retains C as a subset."
Bjarne Stroustrup, The C++ Programming Language, 3rd ed., p. 8.

If you'd bothered to check, you'd see that this has been introduced
as an argument in this debate countless times (pretty much every time
the question has been raised), and someone has invariably pointed out
that it is in no way a satisfactory argument that C and C++ are not
different languages.

There are certainly those, including Stroustrop, who feel that C++ is
"mostly" a superset of C (whatever that might mean). And there are
many of us who do not. Appeals to authority in this case carry no
weight with us, unless that authority is ISO.
 
C

Christian Bau

Keith Thompson said:
C99 6.7.3p7 says:

An object that is accessed through a restrict-qualified pointer
has a special association with that pointer. This association,
defined in 6.7.3.1 below, requires that all accesses to that
object use, directly or indirectly, the value of that particular
pointer. The intended use of the restrict qualifier (like the
register storage class) is to promote optimization, and deleting
all instances of the qualifier from all preprocessing translation
units composing a conforming program does not change its meaning
(i.e., observable behavior).

Though I suppose there might be problems if "restrict" is removed from
the caller but not from the implementation of the function.

I assume you mean "if 'restrict' is removed from the function prototype,
but not from the implementation of the function".

If your code had defined behavior when both the prototype and the
implementation used "restrict", then it still has defined behavior when
"restrict" is removed from the prototype.

However, there is the danger that you write code that you _believe_ has
defined behavior because the prototype had no "restrict", but has indeed
undefined behavior because the implementation used "restrict".
 
J

John Carson

Michael Wojcik said:
If you'd bothered to check, you'd see that this has been introduced
as an argument in this debate countless times (pretty much every time
the question has been raised), and someone has invariably pointed out
that it is in no way a satisfactory argument that C and C++ are not
different languages.

Of course they are two different languages. Who is disputing it?
There are certainly those, including Stroustrop, who feel that C++ is
"mostly" a superset of C (whatever that might mean). And there are
many of us who do not. Appeals to authority in this case carry no
weight with us, unless that authority is ISO.

The question of whether C++ is "mostly" a superset of C turns on two
matters:

1. Knowledge of the specification of the two languages and hence of the
departures from a strict subset-superset relationship.
2. Judgement of the significance of these departures from a strict
subset-superset relationship.

On 1., I feel on safe grounds in appealing to Stroustrup's authority and any
suggestion that his position is based on an erroneous understanding of the
language specifications is plainly silly.

On 2., it is a matter of judgement and a standards body like ISO is never
going to have anything authoritative to say about it. I believe Stroustrup's
judgement carries a lot of weight. It is plainly not authoritative in a
standards sense, but it is nevertheless at least as worthy of consideration
as any other opinion that one might read in a post to this forum.
 
M

Mark McIntyre

Character literals are of type char in C++ and of type int in C, but
I've never seen any programs that depend on this difference other than
ones specifically written to demonstrate it.

I've seen real-world cases where it made a difference. I fail to
recall the exact example, tho I've a feeling it was I/O related
(something to do with reading sizeof 'a' characters?)
 
M

Mark McIntyre

The question of whether C++ is "mostly" a superset of C turns on two
matters:

1. Knowledge of the specification of the two languages and hence of the
departures from a strict subset-superset relationship.
2. Judgement of the significance of these departures from a strict
subset-superset relationship.

you missed out:
3) The occurence of commonly-used C code which is illegal in C++.
On 1., I feel on safe grounds in appealing to Stroustrup's authority and any
suggestion that his position is based on an erroneous understanding of the
language specifications is plainly silly.

And /I/ feel on safe grounds appealing to the authority of the many
experts in CLC, who disagree with Bjarne on this point. No disrespect
to him, but last time I heard, he was a) not impartial in this debate
and b) not a C expert.

But its a futile debate - whether they're sub or supersets of each
other is irrelevant, they're functionalyl quite different languages
and anyone who treats either one as a subset of the other is a Bad
Programmer.
 
K

Keith Thompson

Mark McIntyre said:
But its a futile debate - whether they're sub or supersets of each
other is irrelevant, they're functionalyl quite different languages
and anyone who treats either one as a subset of the other is a Bad
Programmer.

(referring to C and C++)

I agree. On the other hand, there are rare real-world circumstances
in which it can make sense to program in the *intersection* of the two
languages. Code written in this sub-language can look very similar to
well-written C code, with the most significant difference being
casting the result of malloc().

P.J. Plauger, who produces libraries intended to be used either from C
or from C++, is the only person I know of who really has a good reason
to do this (which isn't to say there aren't others).
 
S

Simon Biber

Keith said:
(referring to C and C++)

I agree. On the other hand, there are rare real-world circumstances
in which it can make sense to program in the *intersection* of the two
languages. Code written in this sub-language can look very similar to
well-written C code, with the most significant difference being
casting the result of malloc().

P.J. Plauger, who produces libraries intended to be used either from C
or from C++, is the only person I know of who really has a good reason
to do this (which isn't to say there aren't others).


There are *many* libraries designed to be used either from C or from
C++. Generally they are written in straight C, and the compiled C object
files of the library are linked together with compiled object files of
the user, which could be in any language.

The only part that has to be compiled by both a C compiler and a C++
compiler is the header file, and C++ provides specific constructs to
allow such a thing:

#ifdef __cplusplus
extern "C" {
#endif

/* ... */

#ifdef __cplusplus
}
#endif

This has no effect on a C compiler, which by convention does not define
the __cplusplus macro, but signals to a C++ compiler that the
identifiers declared within are to be linked with a C object file.
 
J

John Carson

Mark McIntyre said:
you missed out:
3) The occurence of commonly-used C code which is illegal in C++.

No, it is covered by 1. and 2. If C code is illegal in C++, then that is a
violation of the subset-superset relationship as per 1. How common/important
this is falls under 2.
And /I/ feel on safe grounds appealing to the authority of the many
experts in CLC, who disagree with Bjarne on this point. No disrespect
to him, but last time I heard, he was a) not impartial in this debate
and b) not a C expert.

I will grant you a) but not b). I think Stroustrup knows every last detail
about what C code is not legal C++ code.
But its a futile debate - whether they're sub or supersets of each
other is irrelevant, they're functionalyl quite different languages
and anyone who treats either one as a subset of the other is a Bad
Programmer.

The whole issue of backward compatibility is one of great importance and
heavily influenced the design of C++. And since C continues to be used,
compatibility issues remain of relevance. Largely for this reason, the new
incompatibilities introduced by C99 have caused a lot of debate on whether
C++ should change in order to incorporate many of the changes to C.
 
P

P.J. Plauger

There are *many* libraries designed to be used either from C or from C++.
Generally they are written in straight C, and the compiled C object files
of the library are linked together with compiled object files of the user,
which could be in any language.

Right, but in our case we have reason to write C code that also
*compiles* as C++ code. And for that reason, we care about the
largest common subset of the two languages.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

Thanks.

The whole issue of backward compatibility is one of great importance and
heavily influenced the design of C++. And since C continues to be used,
compatibility issues remain of relevance. Largely for this reason, the new
incompatibilities introduced by C99 have caused a lot of debate on whether
C++ should change in order to incorporate many of the changes to C.

And C++ is indeed changing, at least in sensible ways. With TR1,
C++ has picked up *all* the C99 library changes. The language
has picked up all the preprocessor changes, and the evolution
subcommittee has triaged the remaining additions to the language.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
M

Mark McIntyre

I will grant you a) but not b). I think Stroustrup knows every last detail
about what C code is not legal C++ code.

I sincerely doubt that. There's probably no human alive who knows
*every last detail*, and I bet you a pound that Bjarne would be the
first to say that he's not The One.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top