Casting the return value of malloc() ?

K

Keith Thompson

Well written C compiles with C++. That is a fact.

It may be the case that it's correct C but not correct C++, and vice
versa.
Here's one of the best pages I've found on the net about C/C++
differences:
<http://david.tribble.com/text/cdiffs.htm>

Here's some code that doesn't work in C++, but does work in C,

#include <limits.h>

int main(void) {
char m[sizeof 'A'];
return m[CHAR_BIT == 8] = 0;
}

This takes advantage of the following difference, that 'A' in C has
type int, but in C++ has type char.
In C this code always works; in C++ it never works.

Incorrect. If sizeof(int)==1 (which implies CHAR_BIT>=16), then it
can work in both C and C++.

Sure, there are plenty of contrived examples of code that works in C
but not in C++. Here's another one:

int main(void)
{
#ifdef __cplusplus
#error
#endif
return 0;
}

Such examples are irrelevant to Nick's claim that "Well written C
compiles with C++.", unless you want to claim that either of the above
examples is well written.

Nick's claim is incorrect because well written C does not cast the
result of malloc (and calloc, and realloc). Avoiding that issue
requires writing code that's less than ideal in C for the sake of C++
compatibility. (Avoiding C++ keywords is less of an issue, since well
written C code doesn't *need* to use them as identifiers.)
 
V

vippstar

It may be the case that it's correct C but not correct C++, and vice
versa.
Here's one of the best pages I've found on the net about C/C++
differences:
<http://david.tribble.com/text/cdiffs.htm>
Here's some code that doesn't work in C++, but does work in C,
#include <limits.h>
int main(void) {
char m[sizeof 'A'];
return m[CHAR_BIT == 8] = 0;
}
This takes advantage of the following difference, that 'A' in C has
type int, but in C++ has type char.
In C this code always works; in C++ it never works.

Incorrect. If sizeof(int)==1 (which implies CHAR_BIT>=16), then it
can work in both C and C++.

Ah yes, correctly noted.
Sure, there are plenty of contrived examples of code that works in C
but not in C++. Here's another one:

int main(void)
{
#ifdef __cplusplus
#error
#endif
return 0;

}

Unless the implementation defines __cplusplus ;-)
Such examples are irrelevant to Nick's claim that "Well written C
compiles with C++.", unless you want to claim that either of the above
examples is well written.

Depends on what Nick means with well written, but let's not stretch
it, I agree.
Nick's claim is incorrect because well written C does not cast the
result of malloc (and calloc, and realloc). Avoiding that issue
requires writing code that's less than ideal in C for the sake of C++
compatibility. (Avoiding C++ keywords is less of an issue, since well
written C code doesn't *need* to use them as identifiers.)

I also agree.
 
J

jameskuyper

Unless the implementation defines __cplusplus ;-)

That's not permitted for a conforming implementation ot C99
(6.10.8p5). I think that was permitted in C90, but I'm not sure. It
was never good QoI, at least not at any time since the birth of C++.
 
I

Ian Collins

Richard said:
(e-mail address removed) said:

True, but of little relevance for the time being.
Now now Richard, some of us do use platforms where the native compiler
is C99.
Why is it not good QoI? It is not the job of any programming language to
avoid treading on the toes of another language. Would we criticise an
implementation's QoI for using the identifier ENVIRONMENT (which is
reserved, like __cplusplus) just because it clashes with COBOL?
How often does C share system or standard library headers with COBOL?
Try putting #define __cplusplus before #include <stdio.h> and see how
far your compiler gets.
 
I

Ian Collins

Richard said:
Ian Collins said:


Sure - and there are some people who do fly on the Space Shuttle.

There's rather a lot more Solaris and AIX developers than space shuttle
passengers.
No, I can't do that, because __cplusplus starts with two consecutive
underscores, which means it's reserved for the implementation.

You can't, but you might be a compiler implementer who's tempted to add
the define to one of your implementation's headers. Doing so would be a
great way to limit sales.
 
C

CBFalconer

Ian said:
.... snip ...

How often does C share system or standard library headers with
COBOL? Try putting #define __cplusplus before #include <stdio.h>
and see how far your compiler gets.

That identifier is reserved for the implementation.
 
I

Ian Collins

Richard said:
Ian Collins said:


Nevertheless, C99 users are a vanishingly small percentage of the C
programming population. The analogy is, I think, a reasonable one.
I think the ratio is somewhat less than 100000000:1, which is about
right for shuttle passengers in the global population.
 
I

Ian Collins

CBFalconer said:
Ian Collins wrote:
.... snip ...

That identifier is reserved for the implementation.
The lost quote from James was "I think that was permitted in C90, but
I'm not sure. It was never good QoI, at least not at any time since the
birth of C++."

QoI applies to the implementation.
 
R

Richard Bos

^^^^^^^^^^^^
Ahem.
er, no.

char *fred = (char*)malloc(42);

is not particularly good C but it will compile with C++.
^^^^^^^^^^^^^^^^^^^^^
Ahem.

Contradiction?

Richard
 
J

James Kuyper

Richard said:
(e-mail address removed) said:


Why is it not good QoI? It is not the job of any programming language to
avoid treading on the toes of another language.

QoI means doing more than the minimum requirement; it means actually
being useful to the user. Code which is written to compile under either
C or C++, achieving that portability with the help of checks for
__cplusplus, is a reality, however much you personally may disapprove of
it. A C90 compiler that predefines __cplusplus is going to cause
problems for such code, and the fact that it was legal for the
implementation to do so won't make it's justifiably angry customers any
happier about that fact.

... Would we criticise an
implementation's QoI for using the identifier ENVIRONMENT (which is
reserved, like __cplusplus) just because it clashes with COBOL?

COBOL is not sufficiently similar to C to encourage the writing of code
that is meaningfully compilable in both languages. I don't remember
enough about COBOL to be sure whether it's possible to use the same kind
of commenting tricks that allow you to write a Fortran program that also
compiles as a C program - but in any event that's not what I'm talking
about.

For C and C++, it's possible to write a program where code which is not
inside a comment, in either language, and which survives conditional
compilation in both languages, constitutes the majority of a significant
program, and gets compiled with essentially the same interpretation in
both languages. That's not possible for C and COBOL.

The ENVIRONMENT keyword was not defined by COBOL for the specific
purpose of allowing a program compilable by both languages to determine
which language it was being compiled for. Also, it is far more plausible
that a C implementation would have a legitimate non-malicious reason to
use ENVIRONMENT, than it is for __cplusplus.

For all these reasons, I wouldn't dream of criticizing a C
implementation that made use of an ENVIRONMENT identifier; I would
criticize any C90 compiler that used a legal loophole to justify
predefining a __cplusplus macro.
 
J

Jean-Marc Bourguet

Richard Heathfield said:
The most useful thing a C compiler could do on encountering __cplusplus
would be to #error That's C++. This is a C compiler. Duh.

That's the most stupidiest thing a C compiler could do.

#ifdef __cplusplus
extern "C" {
#endif

....

#ifdef __cplusplus
}
#endif

is something which is very sensible to put on headers designed to be used
in C (while providing the implementation of the functions there declared)
as well as in C++ (which use that code).

While the interest of compiling function definition in C as well as in C++
is debatable -- I think it is sometimes usefull and my estimation of the
number of cases where it is seems to be somewhere between your estimation
and James' -- having common headers for both languages is usefull.

Yours,
 
R

Richard Tobin

QoI means doing more than the minimum requirement; it means actually
being useful to the user.
[/QUOTE]
The most useful thing a C compiler could do on encountering __cplusplus
would be to #error That's C++. This is a C compiler. Duh.

Surely the point of __cplusplus is to allow code to be conditionalised
for the two languages.
If the code is legal C and legal C++, it will either be bad C, bad C++, or
both. Daft idea. Silly to pander to daft ideas. Harumph, etc.

A header file conditionalised for inclusion in both C and C++ is
certainly ugly, but I don't think it's necessarily a daft idea to
write such header files. It seems like a design flaw that C++
routinely requires such conditionalisation though.

-- Richard
 
J

James Kuyper

Richard said:
James Kuyper said:



The most useful thing a C compiler could do on encountering __cplusplus
would be to #error That's C++. This is a C compiler. Duh.

Not if it's being used to determine whether to conditionally include C
code or C++ code, by someone who wants the compiler to compile it as C
code. The only "useful" thing about treating it as a #error is that it
informs the user that he's selected the wrong C compiler for this purpose.
If the code is legal C and legal C++, it will either be bad C, bad C++, or
both. Daft idea. Silly to pander to daft ideas. Harumph, etc.

I disagree that it's daft. Whether or not it's daft, it's moderately
popular. Even if it were daft, the simple fact that it is also popular
is sufficient to make predefinition of __cplusplus bad QoI.
 
C

CBFalconer

Richard said:
James Kuyper said:



The most useful thing a C compiler could do on encountering
__cplusplus would be to #error That's C++. This is a C compiler.

Not so. We want the universal use in the header file. I.e:

#ifdef __cplusplus
extern "C"
{
#endif
... normal header file ...
#ifdef __cplusplus
}
#endif

and now the module is callable from C and C++.
 
R

Richard Tobin

Richard Heathfield said:
In C89, it can result in a diagnostic message and the failure of the
translation. And opening oneself up to that problem is pretty stupid too.

Do you know of any real implementations where this is true? So much
widely-used software uses #ifdef __cplusplus that I would have thought
that rejecting it would be a serious barrier to sales.

-- Richard
 
R

Richard Tobin

Do you know of any real implementations where this is true?
[/QUOTE]
Do you know that one won't be released tomorrow, with such fantastic
compensating advantages that everyone flocks to it despite its strident
approach to __cplusplus?

I'm pretty sure of that, yes. Certainly sure enough not to worry
about using __cplusplus.

-- Richard
 
J

jameskuyper

Richard said:
CBFalconer said:


No, we don't. We want a clear delineation between the two languages.

Both of you are use "we"; I'm not sure who "we" is in each case, but
it's clear that the two of you are using the terms to describe non-
overlapping sets of people. Why don't the two of you both go back to
"I", unless you are willing to define who "we" are, with sufficiently
precision to clearly exclude the other person?

I have no objection to a "clear delineation between the two
languages", but for me a "clear delineation" means that it's easy for
code which has been written to compile using either language to
determine which language it is being compiled for, which is obviously
incompatible with the meaning that you attach to that phrase.
 
K

Keith Thompson

Richard Heathfield said:
(e-mail address removed) said: [...]
I have no objection to a "clear delineation between the two
languages", but for me a "clear delineation" means that it's easy for
code which has been written to compile using either language to
determine which language it is being compiled for, which is obviously
incompatible with the meaning that you attach to that phrase.

For me, it means use a C++ compiler to compile C++ code, and use a C
compiler to compile C code.

For you, and for most *but not all* C and/or C++ programmers who know
what they're doing.

But, for example, the C++ standard requires support for the C standard
headers; "#include <stdlib.h>" is valid C++ ( "#include <cstdlib>" is
usually preferred, but both are valid). In a typical implementation,
it makes sense to have a single "/usr/include/stdlib.h" file that's
usable by either C or C++ code, using the __cplusplus symbol to
differentiate. Yes, you could do it with two separate files, but then
you'd have to have either a different naming scheme or a different
header search path for the C and C++ compilers. Why add that
complication when it's not necessary? And why not allow authors of C
libraries to make their headers usable for C++ programmers as well?

Sure, the C90 standard doesn't forbid a C implementation to predefine
__cplusplus -- but a compiler that did so would be exhibiting a DS9K
level of perversity (or a serious configuration error in a combined C
and C++ implementation that had better be fixed before the product
sees the light of day). Henry Spencer's warning goes both ways: if
the compiler lies to me, I will get my revenge. It would take a
deliberate blindness to anything outside ISO/IEC 9899:1990 to pretend
that a C compiler that predefines __cplusplus isn't lying.
 

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
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top