Any C code are valid C++ code?

E

E. Robert Tisdale

Dik said:
Probably you have not thought that the C programs involved possibly
were freeware? Obviously, if the person complaining is a customer
or an employer, there is pretty good incentive to make changes.
When somebody complains about a program I put out for free, I will
simply let it go if it is some incompatibility. Only when a (good)
suggestion for change is involved am I inclined to modify. Why
should I put in my free time in changing things that work for me as
I want?

Apparently, it's a question of pride versus professionalism.
 
H

Herbert Rosenau

Victor said:
Since C is a subset of C++ [...]

Wrong premise. Wrong conclusion. The answer to your subj is "no".

Practically speaking, C is a subset of C++.
There are few exceptions.
Each new C++ standard attempts to subsume each new C standard.

Twitsdale proves again that he does not even know what C is. You
should ignore that Twit completely.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
M

Malcolm

Chris Barts said:
Wrong. A common notion that is completely wrong.
Partly wrong. C++ was designed as a superset of C, but in order to avoid
uglification it was accepted that some C scripts would break when compiled
under C++. In fact it turns out that the majority of real C scripts will so
break, unless written with the deliberate intention of compiling under both
langages. This is not difficult to achieve, but does require some care.
 
R

Richard Tobin

Possibly not, but I have no incentive to do so.
[/QUOTE]
Evidently, you don't think of the people who
"have mailed me to ask why one of my C programs doesn't compile"
as customers or employers.

Some of them were customers or potential customers. And of course
I did answer their question: I told them to use a C compiler.

Perhaps it is different for you, but I have the good fortune to be in
a position where just because someone is an employer or customer, I
don't have to abandon my own judgment when answering their questions.

-- Richard
 
M

Mark McIntyre

Mark said:
* different interpretation of multidimensional arrays
What is the difference?

C lets you blur the distinction between ** and *[ ] and [ ][ ]
rather more, especially in function calls.

Eh, what? Could you explain?

This code
void foo(char a[2][2]) {
// do nothing
}

int main(void) {
char** a;
foo(a);
return 0;
}

will cause most C++ compilers to abort, as in C++ there's no possible
conversion from char** to *char[2].
A C compiler will typically complain but compile it anyway, perhaps since
there is often a practical way to perform the conversion.

This may simply be a QOI issue or a case of getting overchummy with the
implementation. But I've come across this in real live production code
written by 3rd parties of great eminence.
 
M

Malcolm

Richard Tobin said:
Perhaps it is different for you, but I have the good fortune to be in
a position where just because someone is an employer or customer, I
don't have to abandon my own judgment when answering their questions.
I've had to write code that was to all intents and purposes C in C++,
because C++ was more in keeping with the image of the company.
 
J

Joona I Palaste

Mark McIntyre <[email protected]> scribbled the following
Mark said:
On Fri, 10 Dec 2004 20:42:03 +0200, in comp.lang.c , "Alex Vinokur"
* different interpretation of multidimensional arrays

What is the difference?

C lets you blur the distinction between ** and *[ ] and [ ][ ]
rather more, especially in function calls.

Eh, what? Could you explain?
This code
void foo(char a[2][2]) {
// do nothing
}
int main(void) {
char** a;
foo(a);
return 0;
}
will cause most C++ compilers to abort, as in C++ there's no possible
conversion from char** to *char[2].
A C compiler will typically complain but compile it anyway, perhaps since
there is often a practical way to perform the conversion.
This may simply be a QOI issue or a case of getting overchummy with the
implementation. But I've come across this in real live production code
written by 3rd parties of great eminence.

I don't understand. Although the C standard says that the type char[2]
is assignable to the type char *, it also says that the type char[2][2]
is definitely *not* assignable to the type char **.
When you indirect into a char[2][2] or a char(*)[2], you expect to find
two bytes of storage right there. However, when you indirect into a
char **, you expect to find a pointer, which then points to another
byte, which might or might not be storage.
 
K

Kenny McCormack

Wrong. A common notion that is completely wrong.


Not true. For example, the following valid C program is not valid C++:

#include <stdlib.h>

int main(void)
{
/* new is a reserved word in C++ */
char new, *buf;

Leaving aside the malloc issues, I'd like to comment on the "new is
a reserved word" issue, in the context of languages in general.

Given that languages always evolve over time and add in new keyords, in some
sense it can never be said that a later version of any language is
a superset of an (or all) previous version(s) of that same language. This
is because some program written to the earlier spec may have used as an
identifier something which is now reserved to the implementation.

I know that C has some features designed to minimize this, such as
reserving certain ranges of words (e.g., str*), features that are not found
in other languages, but still the problem persists. As they say, this is
why they pay us the big bucks...
 
C

Christian Bau

Victor Bazarov said:
Dik T. Winter said:
[...] Why
should I put in my free time in changing things that work for me as
I want?

Why did you feel compelled to publish it in the first place? Can
the same reason apply to compel you to fix it? If not, was it the
_real_ reason you published your code? You don't have to answer.

If I write C code that I didn't intentionally make C++ compatible, then
there is always a chance that for some minor reason the code won't work
if compiled as a C++ program.

However, if you take my C source code, compile it using a C++ compiler,
and you are not capable of fixing whatever minor problems come up, then
perhaps it is dangerous letting you loose on that code.
 
M

Mark McIntyre

Mark McIntyre <[email protected]> scribbled the following
on comp.lang.c:

(snip pretty contrived example of difference between C and C+ compiler)
I don't understand. Although the C standard says that the type char[2]
is assignable to the type char *, it also says that the type char[2][2]
is definitely *not* assignable to the type char **.

Yeah, maybe. But no C compiler I've encountered will reject this code,
while every C++ one will. Like I said, QOI, or what? I belive you're right,
but the fact is, C code that compiles /and runs just fine on multiple
implementations/ won't even compile under C++.
When you indirect into a char[2][2] or a char(*)[2], you expect to find
two bytes of storage right there. However, when you indirect into a
char **, you expect to find a pointer, which then points to another
byte, which might or might not be storage.

Could be, Zaphod.

But remind me, does an array degenerate to a pointer under certain
circumstances, and is a pointer to x roughly the same as the address of a
block of type x? Or not? Or ....My heads hurt.
 
G

Greg Comeau

Mark McIntyre <[email protected]> scribbled the following
on comp.lang.c:

(snip pretty contrived example of difference between C and C+ compiler)
I don't understand. Although the C standard says that the type char[2]
is assignable to the type char *, it also says that the type char[2][2]
is definitely *not* assignable to the type char **.

Yeah, maybe. But no C compiler I've encountered will reject this code,
while every C++ one will. Like I said, QOI, or what? I belive you're right,
but the fact is, C code that compiles /and runs just fine on multiple
implementations/ won't even compile under C++.

Note the MODEs lines:

G:\tmp>como fooa.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:non-strict warnings microsoft C++

"fooa.cpp", line 10: error: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^

1 error detected in the compilation of "fooa.cpp".

G:\tmp>como --A fooa.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C++

"fooa.cpp", line 10: error: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^

1 error detected in the compilation of "fooa.cpp".


"fooa.cpp", line 10: error: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^

1 error detected in the compilation of "fooa.cpp".

G:\tmp>como --c fooa.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:non-strict warnings microsoft C90

"fooa.cpp", line 10: warning: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^


G:\tmp>como --c --A fooa.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C90

"fooa.cpp", line 2: error: expected an expression
// do nothing
^

"fooa.cpp", line 5: warning: parsing restarts here after previous syntax error
}
^

"fooa.cpp", line 5: error: expected a ";"
}
^

"fooa.cpp", line 10: error: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^

3 errors detected in the compilation of "fooa.cpp".

G:\tmp>como --c99 fooa.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:non-strict warnings microsoft C99

"fooa.cpp", line 10: warning: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^


G:\tmp>como --c99 --A fooa.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C99

"fooa.cpp", line 10: error: argument of type "char **" is incompatible with
parameter of type "char (*)[2]"
foo(a);
^

"fooa.cpp", line 10: warning: variable "a" is used before its value is set
foo(a);
^

1 error detected in the compilation of "fooa.cpp".

I can't imagine any other C++ or C compiler acting differently in
their strict modes too, at least to not even put out a warning.
 
D

Dik T. Winter

void foo(char a[2][2]) {
// do nothing
}

int main(void) {
char** a;
foo(a);
return 0;
}

will cause most C++ compilers to abort, as in C++ there's no possible
conversion from char** to *char[2].
A C compiler will typically complain but compile it anyway, perhaps since
there is often a practical way to perform the conversion.

There is *never* a practical way to perform the conversion. What is
happening is that you are invoking an implicit cast between two
incompatible pointer types. A C compiler will also compile:
void foo(double *a) {return; }
int main(void) { int *a; foo(a); return 0: }
which makes just as much sense.

In both cases using 'a' will in general lead to strange behaviour of the
program.
 
D

Dik T. Winter

Dik T. Winter said:
[...] Why
should I put in my free time in changing things that work for me as
I want?

Why did you feel compelled to publish it in the first place? Can
the same reason apply to compel you to fix it? If not, was it the
_real_ reason you published your code? You don't have to answer.

People around me thought the package useful, so I thought it might be
useful to others as well and I put it in my ftp-directory. And I have
been fixing bugs that were reported, even when the bugs only were present
on systems to which I have no access (and happily people that reported
bugs in most cases also provided fixes). But making it compile with C++
is (in my opinion) *not* fixing it.

And apparently it is still thought useful after all those years. It is
part of one of the Linux distributions.
 
D

Dik T. Winter

Yeah, maybe. But no C compiler I've encountered will reject this code,
while every C++ one will. Like I said, QOI, or what? I belive you're right,
but the fact is, C code that compiles /and runs just fine on multiple
implementations/ won't even compile under C++.

The difference between C++ and C is that in C++ conversions between
incompatible pointer types are not allowed. In C they are allowed,
but may produce garbage. For instance, the following will not produce
what you think it should produce:

#include <stdio.h>

void foo(char a[1][1]) {
printf("%c\n", a[0][0]);
return;
}

int main(void) {
char c, *b, **a;
a = &b; b = &c; c = 'd';
foo(a);
return 0;
}
 
E

E. Robert Tisdale

Dik said:
Victor Bazarov writes:
Dik T. Winter wrote:
[...] Why should I put in my free time
in changing things that work for me as I want?

Why did you feel compelled to publish it in the first place? Can
the same reason apply to compel you to fix it? If not, was it the
_real_ reason you published your code? You don't have to answer.

People around me thought the package useful, so I thought [that]
it might be useful to others as well and I put it in my ftp-directory.
And I have been fixing bugs that were reported,
even when the bugs only were present on systems to which I have no access
(and happily people that reported bugs in most cases also provided fixes).
But making it compile with C++ is (in my opinion) *not* fixing it.

And apparently it is still thought useful after all those years.
It is part of one of the Linux distributions.

If you are uncomfortable with maintaining compatibility with C++,
that's a perfectly legitimate reason for not doing so.
But I think that
most good C programmers are good C++ programmers as well
and don't mind supporting customer's legitimate requests
for compatibility.
 
G

Greg Comeau

void foo(char a[2][2]) {
// do nothing
}

int main(void) {
char** a;
foo(a);
return 0;
}

will cause most C++ compilers to abort, as in C++ there's no possible
conversion from char** to *char[2].
A C compiler will typically complain but compile it anyway, perhaps since
there is often a practical way to perform the conversion.

There is *never* a practical way to perform the conversion. What is
happening is that you are invoking an implicit cast between two
incompatible pointer types. A C compiler will also compile:
void foo(double *a) {return; }
int main(void) { int *a; foo(a); return 0: }
which makes just as much sense.

In both cases using 'a' will in general lead to strange behaviour of the
program.

G:\tmp>como --c90 --A incompat.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C90

"incompat.cpp", line 2: error: argument of type "int *" is incompatible with
parameter of type "double *"
int main(void) { int *a; foo(a); return 0; }
^

"incompat.cpp", line 2: warning: variable "a" is used before its value is set
int main(void) { int *a; foo(a); return 0; }
^

1 error detected in the compilation of "incompat.cpp".

G:\tmp>como --c99 --A incompat.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C99

"incompat.cpp", line 2: error: argument of type "int *" is incompatible with
parameter of type "double *"
int main(void) { int *a; foo(a); return 0; }
^

"incompat.cpp", line 2: warning: variable "a" is used before its value is set
int main(void) { int *a; foo(a); return 0; }
^

1 error detected in the compilation of "incompat.cpp".
 
G

Greg Comeau

Yeah, maybe. But no C compiler I've encountered will reject this code,
while every C++ one will. Like I said, QOI, or what? I belive you're right,
but the fact is, C code that compiles /and runs just fine on multiple
implementations/ won't even compile under C++.

The difference between C++ and C is that in C++ conversions between
incompatible pointer types are not allowed. In C they are allowed,
but may produce garbage. For instance, the following will not produce
what you think it should produce:

#include <stdio.h>

void foo(char a[1][1]) {
printf("%c\n", a[0][0]);
return;
}

int main(void) {
char c, *b, **a;
a = &b; b = &c; c = 'd';
foo(a);
return 0;
}

G:\tmp>como --c90 --A notallowed.c
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C90

"notallowed.c", line 11: error: argument of type "char **" is incompatible
with parameter of type "char (*)[1]"
foo(a);
^

1 error detected in the compilation of "notallowed.c".

G:\tmp>como --c99 --A notallowed.c
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:strict errors C99

"notallowed.c", line 11: error: argument of type "char **" is incompatible
with parameter of type "char (*)[1]"
foo(a);
^

1 error detected in the compilation of "notallowed.c".
 
C

Chris Barts

Malcolm said:
Partly wrong. C++ was designed as a superset of C, but in order to avoid
uglification it was accepted that some C scripts would break when compiled
under C++. In fact it turns out that the majority of real C scripts will so
break, unless written with the deliberate intention of compiling under both
langages. This is not difficult to achieve, but does require some care.

Mathematically, it's completely wrong: A subset must either be identical
to the set it is a subset of or it must lack one or more elements (iff
it is a strict subset). (Hey, if you didn't want nitpicking, why are you
in c.l.c?)

So, does derision still fit in with uglification? ;)
 
C

Chris Barts

Kenny said:
Leaving aside the malloc issues, I'd like to comment on the "new is
a reserved word" issue, in the context of languages in general.

Given that languages always evolve over time and add in new keyords, in some
sense it can never be said that a later version of any language is
a superset of an (or all) previous version(s) of that same language. This
is because some program written to the earlier spec may have used as an
identifier something which is now reserved to the implementation.

This is true. I knew it was a somewhat vacuous example when I posted it,
which is why I immediately followed it up with a more substantive one.
My point was that there have been changes great and small to the parts
of C++ some think come direct and unmodified from C.
I know that C has some features designed to minimize this, such as
reserving certain ranges of words (e.g., str*), features that are not found
in other languages, but still the problem persists. As they say, this is
why they pay us the big bucks...

Again, true. C99 isn't a true superset of C89, if you want to be
pedantic, because of things like implicit int being cleaned from the
language, among other things. But C++ is even less of a superset of C99
than C99 is of C89.
 
M

Malcolm

Kenny McCormack said:
Given that languages always evolve over time and add in new keyords, in
some sense it can never be said that a later version of any language is
a superset of an (or all) previous version(s) of that same language.
The C++ folks could have made "@friend" or some similar illegal C construct
the keyword in their language, and allowed continued use of "friend" as an
identifier. Maybe this would have been a good idea.
 

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,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top