Differences between C and C++

I

Ian Collins

Newcomers.

I learned C from K&R1 (there was no "ANSI C" at the time) back around 1983.

I'd been using (K&R) C for a long time on SunOS before I bought the ANSI
compiler for my first Solaris system. Once the need to build kernels
disappeared, so the the need to ship a free compiler!
 
J

James Kuyper

Looking at the chart on the wall C was incrementally developed from
BCPL that came from CPL.

in the 1970's we had K&R C, the first definition.
ANSI/ISO C was standardised in 1989/90 and then ISO C in 95 and 99

C++ was developed from "C with Classes" (1980) which was developed
from 1975 K&R C AND Simula 68

And C with Classes was originally intended to be no more than an
extension to C, a concept that never ceased to influence the development
of C++, even long after it had diverged enough that it was clearly a
different language.
C++ came about in 1985 ish with influences from Algo 68 and additional
input from Simula 68

And it was developed with an explicit design philosophy, which
influenced a great many of the design decisions, to maintain a fair
amount of backwards compatibility with C. In fact, there's been a lot of
criticism of precisely those design decisions which were made to retain
a level of backwards compatibility.
So there is a LOT of Simula in C++ as well as Algo

Moving on... in 1990 we had C++ ARM,( Annotated Reference Manual not
ARM MCU's ) developed from C++ but also with influences from Ada, ANSI
C, ML and CLu

C++ was further developed into the mid 90's when it became an ISO
standard.

And the C and C++ committees interacted strongly, with the goal of
avoiding gratuitous incompatibilities between C and C++.
So whilst sharing syntax that appears similar C and C++ diverged in
197* and whilst C carried on in one direction C++ was a hybrid of C and
Simula which was developed independently from C with influenced from 5
other languages.

To summarize my comments on your history: C++ didn't just diverge wildly
from C randomly; it was deliberately kept fairly close to C, far closer
than it would have been had there not been a deliberate decision to
retain a fair amount of C compatibility. C is NOT just a language that
inspire the design of C++, the connections between the two languages are
much tighter than that.
The confusion generally arises because in the early days (from memory)
a front end call C-Front was used to translate C++ into C for
compilation until C++ compilers were built from scratch.

Thus the myth started that C++ was a super set of C.

I doubt that awareness of that historical background has as much to do
with that "myth" as other, more important things, such as the following
list of similarities, which I'll organize by sections of the C standard:

6.4.1: Virtually every C90 keyword is also a C++ keyword, and when used
in typical C code, most of them have essentially the same meaning as in
C++. Also, many of the new C90 keywords are also keywords in C++03.

6.4.2: The rules for legal identifiers in C are almost identical to
those of C++.

6.4.3: UCNs work essentially the same in both languages.

6.4.4: Most C90 constants are C++ literals, almost always with the same
meaning (the biggest difference being the type of 'a').

6.4.5: string literals are pretty much the same in both languages,
except that they are const-qualified in C++, but they're not safely
writable in either language, so that won't have much effect on
well-written C code.

6.4.6: Every C punctuator is also a C++ punctuator.

6.4.7: Both languages have essentially the same rules for header names.

6.4.8: Both languages have essentially the same rules for preprocessing
numbers.

6.4.9: Every C90 comment is also a C++ comment; and C99 comments are
essentially the same as C++ comments.

6.5: Every C90 expression is also a C++ expression, and when used in
typical C code, almost always has the same meaning in C++.

6.6: All C constant expressions are also C++ constant expressions.

6.7: Most C declarations carry essentially the same meaning in C++,
though there are some changes the scope and name space rules.

6.8: Every C statement type is also a C++ statement type. While some of
the details are different in C++, in typical C code, they work the same
way in both languages.

6.10: Preprocessing directives: every C90 preprocessing directive is
also a C++ preprocessing directive, with essentially the same meaning.

7: The entire C standard library was incorporated with only a few
modifications into the C++ standard library. While things like <cstdio>
and std::printf do exist, you don't have to use them: <stdio.h> and
printf() will work almost exactly as they do in C.

I put this list together in a hurry - some of my "almost" and
"essentially" qualifiers may have been unnecessary, and I may have
failed to use them on some statements where they were needed - but I'm
sure that I didn't make enough errors in the above summary to change my
final conclusion:

The concept that C is a strict subset of C++ is indeed a myth, but
mainly because of the word "strict". The concept that C doesn't even
come close to being a subset of C++ is a myth that strays much farther
from the truth.
 
M

Michael Press

James Kuyper said:
Yes, that is one of the many features that are different, which does not
fall under either of those categories. While numerous, those features
constitute a tiny fraction compared to the number of features that C
shares with C++.

I do not consider the fraction tiny. For this
discussion only I stipulate that the fraction is tiny.
The absolute number of differences of constructions
valid in only one of C and C++, and differences in
behavior, and impositions of style such as extern "C"
is large enough to make writing code that will compile
as C and C++ code or can easily be made to compile as C
and C++ code sufficiently burdensome as to be only
worth doing for money. In short that there is too much
well made C code that does not compile and cannot be
easily made to compile as C++ code to conclude that C
is a subset of C++.

If C is a subset of C++, then we can now abandon C and
all take to writing in C++ what we previously wrote in C.

Both are Turing complete for sufficiently small values
of complete. That is it.
 
M

Michael Press

[...]
6.4.1: Virtually [...]
most of them have essentially [...]
many
6.4.2: [...]
almost identical to
6.4.3: [...]
work essentially the same. [...]
6.4.4: Most [...]
almost always [...]
6.4.5:
pretty much the same [...]
except [...]
won't have much effect [...]
6.4.6: Every C punctuator is also a C++ punctuator.

6.4.7: [...]
essentially the same [...]
6.4.8: [...]
essentially the same [...]
[...]
essentially the same [...]
6.5: [...]
almost always [...]
6.6: All C constant expressions are also C++ constant expressions.

6.7: Most [...]
essentially the same [...]
though [...]
6.8: Every C statement type is also a C++ statement type. While some of
the details are different in C++, in typical C code, they work the same
way in both languages.

6.10: [...]
essentially the same meaning.

7: [...]
only a few
modifications [...]
almost exactly [...]

I put this list together in a hurry - some of my "almost" and
"essentially" qualifiers may have been unnecessary, and I may have
failed to use them on some statements where they were needed - but I'm
sure that I didn't make enough errors in the above summary to change my
final conclusion:

The concept that C is a strict subset of C++ is indeed a myth, but
mainly because of the word "strict". The concept that C doesn't even
come close to being a subset of C++ is a myth that strays much farther
from the truth.
 
C

Chris H

James Kuyper said:
To summarize my comments on your history: C++ didn't just diverge
wildly from C randomly; it was deliberately kept fairly close to C, far
closer than it would have been had there not been a deliberate decision
to retain a fair amount of C compatibility. C is NOT just a language
that inspire the design of C++, the connections between the two
languages are much tighter than that.
6.4.1: Virtually every C90 keyword is also a C++ keyword

Ie Most
6.4.2: The rules for legal identifiers in C are almost identical to
those of C++.

Almost identical == different
6.4.3: UCNs work essentially the same in both languages.

Essentially they same but not the same
6.4.4: Most C90 constants are C++ literals, almost always with the same
meaning (the biggest difference being the type of 'a').

*Almost* always the same

6.4.5: string literals are pretty much the same in both languages,
except that they are const-qualified in C++, but they're not safely
writable in either language, so that won't have much effect on well-
written C code.

Pretty much the same *except*

6.4.7: Both languages have essentially the same rules for header names.

6.4.8: Both languages have essentially the same rules for preprocessing
numbers.

"Essentially the same" not actually the same
6.5: Every C90 expression is also a C++ expression, and when used in
typical C code, almost always has the same meaning in C++.

"Almost" always
6.7: Most C declarations carry essentially the same meaning in C++,
though there are some changes the scope and name space rules.

"Most" again

6.8: Every C statement type is also a C++ statement type. While some of
the details are different in C++, in typical C code, they work the same
way in both languages.


"Whist some details are different"

7: The entire C standard library was incorporated with only a few
modifications into the C++ standard library. While things like <cstdio>
and std::printf do exist, you don't have to use them: <stdio.h> and
printf() will work almost exactly as they do in C.

"Almost exactly" but not identically
I put this list together in a hurry - some of my "almost" and
"essentially" qualifiers may have been unnecessary, and I may have
failed to use them on some statements where they were needed - but I'm
sure that I didn't make enough errors in the above summary to change my
final conclusion:


Agreed. But my point is that they are SIMILAR but different and these
small differences scattered around very similar syntax is dangerous
when people treat C and C++ as a subset/superset and this is where
errors occur particularly using C source in a C++ compiler and Vice
versa
The concept that C is a strict subset of C++ is indeed a myth, but
mainly because of the word "strict".

We agree.
The concept that C doesn't even come close to being a subset of C++ is
a myth that strays much farther from the truth.

I would disagree but them most of my work in in safety critical and high
reliability SW
 
C

Chris H

That is a long list of "if" , "maybe" , "almost", "similar" and "pretty
much"

Or in other words "Different"



Michael Press said:
[...]
6.4.1: Virtually [...]
most of them have essentially [...]
many
6.4.2:
[...]
almost identical to
6.4.3: [...]
work essentially the same. [...]
6.4.4: Most [...]
almost always [...]
6.4.5:
pretty much the same [...]
[...]
won't have much effect [...]
6.4.6: Every C punctuator is also a C++ punctuator.

6.4.7: [...]
essentially the same [...]
[...]
essentially the same [...]
[...]
essentially the same [...]
[...]
almost always [...]
6.6: All C constant expressions are also C++ constant expressions.

6.7: Most [...]
essentially the same [...]
[...]
6.8: Every C statement type is also a C++ statement type. While some of
the details are different in C++, in typical C code, they work the same
way in both languages.

6.10: [...]
essentially the same meaning.

7: [...]
only a few
modifications [...]
almost exactly [...]

I put this list together in a hurry - some of my "almost" and
"essentially" qualifiers may have been unnecessary, and I may have
failed to use them on some statements where they were needed - but I'm
sure that I didn't make enough errors in the above summary to change my
final conclusion:

The concept that C is a strict subset of C++ is indeed a myth, but
mainly because of the word "strict". The concept that C doesn't even
come close to being a subset of C++ is a myth that strays much farther
from the truth.
 
J

James Kuyper

I do not consider the fraction tiny. For this
discussion only I stipulate that the fraction is tiny.
The absolute number of differences of constructions
valid in only one of C and C++,

I'll readily concede that the differences between C++ and the common
subset is large, but the differences between C and the common subset are
quite small, and my discussion was entirely about those differences.

....
If C is a subset of C++, then we can now abandon C and
all take to writing in C++ what we previously wrote in C.

I never claimed that C is a subset of C++; only that the common subset
is almost identical to C, and that the common subset contains enough of
C's features to be, in itself, a language almost powerful and useful as
C. In many ways, the common subset is better than C, by reason of not
supporting many features of C that programmers should not be using, such
as non-prototype function declarations.
 
J

James Kuyper

On 02/11/2011 04:39 AM, Chris H wrote:
....
Ie Most ....
Almost identical == different

Yes, and different != distinct
Essentially they same but not the same ....
*Almost* always the same ....
Pretty much the same *except* ....
"Essentially the same" not actually the same ....
"Almost" always ....
"Most" again ....
"Whist some details are different" ....
"Almost exactly" but not identically

Thank you for noticing; I tried to be careful to include all of the
qualifiers needed to make my statements accurate. I'm glad to see that
you don't disagree with any of them, neither by implying that the
differences are significantly larger (or smaller) than implied by those
qualifiers.
Agreed. But my point is that they are SIMILAR but different and these

I was talking about the similarities, without in any way, shape, or form
implying that there were no differences. Why would you think otherwise,
after having so carefully noted all of the qualifiers that I inserted
specifically to express that concept?

....
We agree.


I would disagree but them most of my work in in safety critical and high
reliability SW

The differences between two arbitrarily chosen languages could be so
numerous as to preclude, for all practical purposes, reliable conversion
of safe software from one language to the other; yet that would not
exclude the possibility that the differences are few in comparison with
the similarities. I would deny emphatically that C and C++ even come
close to being that different.
 
C

Chris H

James Kuyper said:
On 02/11/2011 04:39 AM, Chris H wrote:
...

Yes, and different != distinct


Thank you for noticing; I tried to be careful to include all of the
qualifiers needed to make my statements accurate. I'm glad to see that
you don't disagree with any of them, neither by implying that the
differences are significantly larger (or smaller) than implied by those
qualifiers.


I was talking about the similarities, without in any way, shape, or
form implying that there were no differences. Why would you think
otherwise, after having so carefully noted all of the qualifiers that I
inserted specifically to express that concept?

...

The differences between two arbitrarily chosen languages could be so
numerous as to preclude, for all practical purposes, reliable
conversion of safe software from one language to the other; yet that
would not exclude the possibility that the differences are few in
comparison with the similarities. I would deny emphatically that C and
C++ even come close to being that different.


I am being a devils advocate. If you approach the subject thinking these
are two different but similar languages you should have few problems. I
was only trying to stop those people who thing C is a subset of C++ and
assume because they look similar they are interchangeable

BJ has written that there is no such language as C/C++ and that whilst
very similar there are many difference to trap the unwary.
 
I

Ian Collins

I never claimed that C is a subset of C++; only that the common subset
is almost identical to C, and that the common subset contains enough of
C's features to be, in itself, a language almost powerful and useful as
C. In many ways, the common subset is better than C, by reason of not
supporting many features of C that programmers should not be using, such
as non-prototype function declarations.

Which is why I started building one project (not for the target which
had a crappy C compiler) using a C++ compiler to flush out a whole pile
of smelly bugs!
 
J

Joshua Maurice

Virtually anything which uses malloc() for something other than "char *"
would need to be changed to work in C++.  Hardly "clearly contrived".

I've actually been having a lot of discussions on this recently in
comp.std.c, and some others in comp.std.c++ and comp.lang.c+
+.moderated. It's my position, and at least one person on the
standard's committee for one of the languages, that simple idiomatic C
code (with additional cast) like:
#include <stdlib.h>
typedef struct T { int x; int y; } T;
int main()
{
T* t = (T*) malloc(sizeof(T));
t->y = 1;
return t->y;
}
Should be well defined C code and well defined C++ code. I doubt any C+
+ compiler writer or anyone on the C++ standards committee would
disagree, even though the C++ rules in its standard on this subject
are quite broken. (C's rules are also pretty broken as well. I would
refer you to the thread on comp.std.c.)
 
K

Keith Thompson

Ian Collins said:
Which is why I started building one project (not for the target which
had a crappy C compiler) using a C++ compiler to flush out a whole pile
of smelly bugs!

Quoting from the preface to the 2nd edition of Kernighan & Ritchie's
_The C Programming Language_ (K&R2):

We used Bjarne Stroustrup's C++ translator extensively for local
testing of our programs, and Dave Kristol provided us with an ANSI C
compiler for final testing.
 
K

Keith Thompson

Joshua Maurice said:
I've actually been having a lot of discussions on this recently in
comp.std.c, and some others in comp.std.c++ and comp.lang.c+
+.moderated. It's my position, and at least one person on the
standard's committee for one of the languages, that simple idiomatic C
code (with additional cast) like:
#include <stdlib.h>
typedef struct T { int x; int y; } T;
int main()
{
T* t = (T*) malloc(sizeof(T));
t->y = 1;
return t->y;
}
Should be well defined C code and well defined C++ code. I doubt any C+
+ compiler writer or anyone on the C++ standards committee would
disagree, even though the C++ rules in its standard on this subject
are quite broken. (C's rules are also pretty broken as well. I would
refer you to the thread on comp.std.c.)

Some minor quibbles:

I've argued before that "int main()" is not well defined in C, but C++
supports "int main(void)" specifically for C compatibility.

It's always possible for malloc() to fail.

Returning the value 1 from main is not portable.

But yes, I agree with your point. Most well-written C code is
probably not valid C++ code, but almost all well-written C code can
be made into valid C++ code "with minor re-writes", such as adding
casts on malloc calls. (The result is not likely to be well-written
C++ code, but that's not the point.)
 
J

Joshua Maurice

Some minor quibbles:

I've argued before that "int main()" is not well defined in C, but C++
supports "int main(void)" specifically for C compatibility.

It's always possible for malloc() to fail.

Returning the value 1 from main is not portable.

But yes, I agree with your point.  Most well-written C code is
probably not valid C++ code, but almost all well-written C code can
be made into valid C++ code "with minor re-writes", such as adding
casts on malloc calls.  (The result is not likely to be well-written
C++ code, but that's not the point.)

I was trying to make a much smaller point. I believe that Kenneth
Brody was arguing that in C++, you can not take the result of malloc,
cast it to a C-type, and write and write through that pointer. I
disagree, and I stated my disagreement.
 
M

Michael Press

James Kuyper said:
I'll readily concede that the differences between C++ and the common
subset is large, but the differences between C and the common subset are
quite small, and my discussion was entirely about those differences.

...

I never claimed that C is a subset of C++; only that the common subset
is almost identical to C, and that the common subset contains enough of
C's features to be, in itself, a language almost powerful and useful as
C. In many ways, the common subset is better than C, by reason of not
supporting many features of C that programmers should not be using, such
as non-prototype function declarations.

Okay. Thanks. I should figure out if I am using
bad practices. Certainly do not write non-prototype
function declarations. Only cast regularly to force
an integer type to a double.

Got into an OT discussion once when somebody put
"int main() {...}" in a message. I mentioned it,
and was told it is entirely legal in C++.
 
W

who flung dung

"int main() {...}


I was under the impression that an empty parameter list in a function
(as above) is allowed so that legacy code is not broken and that we
should now write

int main(void) {...}

Then, I am only a recreational programmer and and as long as the
program works as intended I am a happy camper.
 
J

James Kuyper

Pay close attention to the following:
....
....
I was trying to make a much smaller point. I believe that Kenneth
Brody was arguing that in C++, you can not take the result of malloc,
cast it to a C-type, and write and write through that pointer. I
disagree, and I stated my disagreement.

That means that you totally misunderstood Kenneth's point. All that he
actually said was that most C code calling malloc() would need to be
re-written; he was implicitly assuming that you knew why it would need
to be re-written. You seem to assume that he was suggesting that the
code would need to have the cast removed. Why? Most C code, especially
well-written code, does NOT have that cast, which is precisely the
reason it would need to be rewritten. He was not suggesting that it
would need to be re-written because the cast was illegal in C++; in
fact, the reason why it would need to be re-written that the cast is
mandatory in C++.

Incidentally, the reason why Keith says that (T*)malloc() would not be
well-written C++ code is not because it's the wrong way to use malloc()
in C++: you can use malloc() in C++, and if you choose to do so, that's
the way to do it. But in C++, in most contexts where a C programmer
would use malloc(), a good C++ programmer would use either the 'new'
operator, or more likely, an object of some container type (probably
one the C++ standard library's standard container types).
 
S

Seebs

That is a long list of "if" , "maybe" , "almost", "similar" and "pretty
much"
Or in other words "Different"

UK English and US English are pretty comparable. There are cases where
they differ. Heck, there are sentences which have their meaning completely
reversed between the two languages. But most people tend to view them as
so similar that some call them "dialects" of the same "language".

I'd tend to view the "common subset" parts of C and C++ as being about like
US and UK English. It would be foolhardy to ignore the differences, but that
doesn't mean they're a huge deal for most writers.

-s
 
J

Joshua Maurice

Pay close attention to the following:
...


That means that you totally misunderstood Kenneth's point.  All that he
actually said was that most C code calling malloc() would need to be
re-written; he was implicitly assuming that you knew why it would need
to be re-written. You seem to assume that he was suggesting that the
code would need to have the cast removed. Why? Most C code, especially
well-written code, does NOT have that cast, which is precisely the
reason it would need to be rewritten. He was not suggesting that it
would need to be re-written because the cast was illegal in C++; in
fact, the reason why it would need to be re-written that the cast is
mandatory in C++.

Incidentally, the reason why Keith says that (T*)malloc() would not be
well-written C++ code is not because it's the wrong way to use malloc()
in C++: you can use malloc() in C++, and if you choose to do so, that's
the way to do it. But in C++, in most contexts where a C programmer
would use malloc(), a good C++ programmer would use either the 'new'
operator, or more likely, an object of some container type (probably
one the C++ standard library's standard container types).

I'm sorry. I misunderstood. Let me clear some things up.

I know idiomatic C code won't have the cast on the return of malloc.
Sorry that I mistyped that.

I thought the context of this thread was the discussion of the
differences in defined behavior between text as source code input for
the two programming languages, not the differences between good style
or idiomatic usage.

Moreover, with that context, I thought that he meant that idiomatic C
code using malloc would not have defined behavior in C++, even with
the added cast. When I hear rewrite, that implies large changes have
to be made - that certain underlying assumptions of the code are going
to be changed. Adding a cast is not a rewrite.
 
J

James Kuyper

....
Moreover, with that context, I thought that he meant that idiomatic C
code using malloc would not have defined behavior in C++, even with
the added cast. When I hear rewrite, that implies large changes have
to be made - that certain underlying assumptions of the code are going
to be changed. Adding a cast is not a rewrite.

It was Keith who first talked about "re-writes", and he prefixed that
word with the adjective "minor" - that makes it pretty hard to justify
assuming he was talking about large changes.

Kenneth only used the word "changed", without any adjectives to suggest
how big of a change he was talking about. I think you read more into his
statement than he put into it.
 

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,085
Messages
2,570,597
Members
47,218
Latest member
GracieDebo

Latest Threads

Top