C/C++ guidelines

O

Old Wolf

There is code which is well formed in both C90 and C99 which will
do different things in the two versions of the language, but I've
never heard anyone suggesting *not* to try to write code in their
common subset.

People suggest it regularly on this NG. In fact it is
impossible to write a useful program in the common
subset that does not use deprecated features of C++
(such as including standard headers ending in ".h").
 
P

Phlip

Old said:
People suggest it regularly on this NG. In fact it is
impossible to write a useful program in the common
subset that does not use deprecated features of C++
(such as including standard headers ending in ".h").

Last I heard no compiler actually implements the C++ Standards. If so, by
that logic, no true C++ program has ever been written!
 
P

Peter J. Holzer

[...] in C you should not cast the result of malloc, because
doing that might introduce subtle errors [...]

For example?

Failure to #include <stdlib.h> going undetected.
Huh?

So it's _not_ the usage of the cast (as such) which "might introduce
subtle errors" but forgetting to include <stdlib.h>.

Splitting hairs. If the cast were not there, you'd be warned about the
missing prototype.

No, you'd be warned about a conversion from integer to pointer.
By inserting the cast, you mask the other error.

Maybe, maybe not. If the compiler warned about a missing prototype, it
would do so with or without the cast.

Its a warning and (in C89 at least) no diagnosis is actually required.
So you're relying on Quality of Implementation.

If you rely on getting a useful diagnostic for an implicit conversion
from int to a pointer, you are also relying on Quality of
Implementation. The standard only says that "a diagnostic" is required,
but doesn't require any useful information to be included in the
diagnostic. "Warning: This program may contain errors" is perfectly
acceptable as far as the standard is concerned.

You may have a point if you claim that almost all compilers do warn
about the implicit conversion while only a few warn about the implicit
declaration, but you would have to back up this claim with facts.

As a tiny counter example, I submit that gcc 4.1.2 without any -W*
options warns:

foo.c:3: warning: incompatible implicit declaration of built-in function
‘malloc’

both with and without the cast. It doesn't warn about the implicit
conversion in this case (but it does if I replace "malloc" with "foo").

hp
 
J

Jerry Coffin

[email protected] says... said:
But the C90 standard, even though it's "officially" obsolete, is
almost universally supported. If you write C90-conforming code with
no extensions, and manage to avoid exceeding implementation-defined
limits, you can be reasonably confident that your code will compile
and run with any existing compiler invoked with appropriate options.

That's true iif you ignore all the pre-standard compilers out there. I
haven't checked recently, but up through the late '90s or so, Sun still
shipped a _thoroughly_ pre-standard C compiler with their OS, just for
one example.

At least at that time, it was _much_ cheaper and easier to get Comeau
C++ for that system than it was to get Sun's reasonably up-to-date C
compiler (unfortunately, for political reasons when I had to do it, I
was overridden, and ended up with Sun's development system anyway).

Realistically, you need to start from a reasonable understanding of the
kinds of things your code targets, and from that the kinds of systems it
might make sense to port it to. Limiting the language so you can get
your high-end scientific code to be accepted by a compiler that targets
tiny embedded processors would be silly. Conversely, limiting your motor
controller code so it would theoretically be accepted by Cray's compiler
would be equally silly.

Code that makes much sense on a huge range of systems is really quite
rare. Some libraries for things like simple math might make sense across
most of them, but there just aren't very many complete applications that
make sense on both a Cray and a Microchip PIC...
 
R

Richard Tobin

That's true iif you ignore all the pre-standard compilers out there. I
haven't checked recently, but up through the late '90s or so, Sun still
shipped a _thoroughly_ pre-standard C compiler with their OS, just for
one example.

But I never heard of anyone using it. You could just use gcc. For
most people, accommodating pre-standard compilers makes no more sense
than allowing for 110 baud teletypes.

-- Richard
 
J

Jerry Coffin

[email protected] says... said:
We tend to assume here in comp.lang.c that most questions we get are
about hosted implementations, unless the questioner explicitly says
otherwise. That's usually a valid assumption; it's been plausibly
claimed that most C programming is done for embedded systems, but most
people learning C use hosted implementations (commonly Windows or
something Unix-like).

That's reasonable, as far as it goes. I'd call "maximum portability" a
fairly explicit statement that it's not intended specificlaly for hosted
implementations, but maybe that's just me.
The cost of writing most of your code in the intersection of C90 and
C99 is minimal, and it's good practice anyway (unless you're willing
to limit yourself to implementations that support some or all of the
new C99 features).

That depends _heavily_ upon what you're doing and what you compare to.
If you really want maximum portability, C90 doesn't get even close, but
the lengths you go to for truly maximum portability can make the code
drastically more expensive. Just for one example, at one time I flat-out
gave up on porting some code because I couldn't sort out what bits it
needed from what headers (and this was GNU code that had already been
ported to quite a few platforms too).
You may be right, but I don't think we have enough information to
assume that. The OP's single sentence didn't tell us how much thought
went into setting the requirement.

When you get down to it, my point is that restricting yourself to the
common subset of C and C++ doesn't gain you much of anything beyond (for
example) just using C the way it as inteded to be used. For that matter,
restricting yourself from using C++ gains very little either -- at one
time there were quite a few systems that supported C but not C++. That
day is long gone, and I know of very few (if any systems) that have even
reasonably compliant implementations of C89 but no C++ compiler (in
fact, for a while there were a fair number of systems for which the
closest thing to a conforming implementation of C WAS their C++
compiler).
 
R

rafaelc

Last I heard no compiler actually implements the C++ Standards. If so, by
that logic, no true C++ program has ever been written!

Compilers implement C++ standards, only not all of it. Therefore there are
plenty valid C++ programs out there, just not a program that uses all the
features described in the standard. Well, nowdays there may be some compilers
that caught up with C++ standards. But g++ certanly isn't one of them.
 
J

Jerry Coffin

But I never heard of anyone using it. You could just use gcc. For
most people, accommodating pre-standard compilers makes no more sense
than allowing for 110 baud teletypes.

That depends on your market -- for hosted systems, you're absolutely
correct. For small embedded systems, there are quite a few compilers
that don't make much attempt at conforming with the standard. If you
look closely, even the ones that have "ANSI compliant" in big letters on
the box really aren't very close. In this market, "ANSI compliant"
often means something like "accepts prototypes and maybe even typedefs."
 
P

Pierre Asselin

In comp.lang.c Robbie Marshall said:
I'm about to embark on a new project and for maximum portability we've
been asked to code it in the common subset of C and C++.

Ow! You're asking for trouble. The common subset is going to be
mostly C, with restrictions based on appendix B in Stroustrup --but
I'm not sure that's up to date. Someone else mentioned Harbison
and Steele 5th edition, try that. You can also google for "differences
between C and C++" and start reading.

It makes sense to keep your *headers* in the common subset so you
can easily provide a C++ interface, but doing it over the whole
codebase is a lot more delicate.
 
K

Keith Thompson

Tor Rustad said:
That was a bit drastic, the code should compile under both C and C++,
and a C compiler will not detect if reserved C++ keywords are used. To
test this, a C++ compilation is rather useful.

I was actually suggesting a change in the requirement; I should have
been clearer about that. If maximum portability is the goal, then
sticking to C90 and not worrying about C++ compatibility is likely to
be the best approach; the #ifdef/#error thing is intended to enforce
the modified requirement.

The only reason I can think of to require C++ source compatibility is
if the OP's customers need to compile the source code themselves and
are unwilling to use C compilers (or if it's a purely political
requirement). In that case, my suggestion doesn't apply.
IMO, this is better:

#ifndef __STDC__
#warning "Non Standard C compiler used"
#endif

You also need to check for __STDC__ being defined as something other
than 1. Some compilers have used __STDC__==0 to indicate partial
compliance.
above, can be extended to detect C95 and C99, via __STDC_VERSION__ checks.
Yup.

For C++ compilation, the C header files need this:

#ifdef __cplusplus
extern "C" {
#endif

..bla. bla...

#ifdef __cplusplus
}
#endif

<OT>Yes -- but for C++ compilation, they're C++ header files, not C
header files.</OT>
 
C

CBFalconer

Jerry said:
.... snip ...

That's true iif you ignore all the pre-standard compilers out
there. I haven't checked recently, but up through the late '90s or
so, Sun still shipped a _thoroughly_ pre-standard C compiler with
their OS, just for one example.

At least at that time, it was _much_ cheaper and easier to get
Comeau C++ for that system than it was to get Sun's reasonably
up-to-date C compiler (unfortunately, for political reasons when
I had to do it, I was overridden, and ended up with Sun's
development system anyway).

But, since a C++ compiler doesn't compile C, you still didn't have
a C compiler. Why didn't you just get GNU stuff? The price is
certainly right.
 
L

LR

Phlip said:
Last I heard no compiler actually implements the C++ Standards. If so, by
that logic, no true C++ program has ever been written!

I think you might be able to say that no C++ program has been compiled
by a compiler that fully implements the C++ standard. There is no
requirement for a compiler to exist for a program to be written. Is there?

LR
 
K

Keith Thompson

Erik Wikström said:
Nor is there a good reason to do so, since the common subset is a
"lesser" C, why not not just write C instead. The common subset does
not have any of the "additions" that C++ brings (objects, templates,
etc.) and it does not even have all of C, so what is the gain of using
the common subset? The only thing you gain is the headache of avoiding
those cases where the semantics differ.

I've dropped comp.lang.c++ from the newsgroups list.

If you want to write maximally portable C, it does make sense to stick
to the intersection of C90 and C99. This doesn't really lose anything
relative to just using C90. It means avoiding certain features
(implicit int, implicit function declarations) that are poor style
anyway, and avoiding C99-specific keywords.

Support for C90 is almost universal, but you can potentially
future-proof your code by making it legal C99 as well. If, some day,
there are compilers that support C99 but not C90, your code will still
compile. Perhaps more realistically, your code is more likely to work
if someone compiles it in a mode that supports C90 plus extensions.
 
P

Phlip

Last I heard no compiler actually implements the C++ Standards. If so, by
I think you might be able to say that no C++ program has been compiled by
a compiler that fully implements the C++ standard. There is no
requirement for a compiler to exist for a program to be written. Is
there?

Theeennnn... you can write a program that's well-formed and well-behaved for
both C and C++, right?
 
R

Richard Heathfield

LR said:
I think you might be able to say that no C++ program has been compiled
by a compiler that fully implements the C++ standard. There is no
requirement for a compiler to exist for a program to be written. Is
there?

No. For one thing, there are such things as interpreters! For another, the
concept of a programming language is different from the concept of an
implementation capable of translating programs written in that language.

Furthermore, the existence of an implementation that correctly implements a
subset of a programming language is sufficient for correct programs in
that language to be translated correctly, provided only that those
programs keep themselves strictly within the implemented subset. Thus, for
example, it would be perfectly possible to write a legal C program and
translate it using an implementation that does not provide, say, FLT_MAX,
provided that the program does not use FLT_MAX. (I suspect that
practically all of my own programs could successfully be translated by
such an implementation.)
 
J

Jerry Coffin

[email protected] says... said:
But, since a C++ compiler doesn't compile C, you still didn't have
a C compiler. Why didn't you just get GNU stuff? The price is
certainly right.

At least AFAIK, Comeau always ships both a C and C++ compiler together.

Unfortunately, gcc was unacceptable for exactly the same reasons as
Comeau: somebody upstairs decided that spending more money translated
more or less directly to a better chance the project would succeed, so
we ended up with Sun's compiler.

As I recall, however, we ended up getting and installing Sun's compiler
to satisfy the PHBs, then actually used gcc for the real work... :)
 
R

Richard Heathfield

Phlip said:
Theeennnn... you can write a program that's well-formed and well-behaved
for both C and C++, right?

Yes, that can be done. Below, I quote Jeremy Dilatush's "Hello world"
program, which is (almost!) legal as C, as TCL, as Perl, and as a shell
script.

I am not sure which side of the argument, if any, this program supports!

#define NAME hello.c
#define DESCRIP many languages at once (tcl, perl 4 & 5, sh, C)
#define AUTHOR Jeremy Dilatush
#define DATE 7/31/96
#define dummy \
eval qq[qq? 2> /dev/null
#if 0
#\
echo 'Hello world!'; exit 0 # shell part
puts "Hello world!"; exit 0
#endif

/* C part */

#include <stdio.h>

int main(void)
{
printf ("Hello world!\n");
return 0;
}

#define dummy2(perl) \
?]; print "Hello world!\n"; exit 0 # perl part
 
L

LR

Phlip said:
Theeennnn... you can write a program that's well-formed and well-behaved for
both C and C++, right?

I'm not sure how that follows.



However, it's been some time since I wrote code for a C compiler, so I
will appreciate any corrections pointing out how this might not be valid
C, but I think the answer is:

int main() {
return 0;
}

And so the answer would be yes. Right?

LR
 
L

LR

Richard said:
Phlip said:
Theeennnn... you can write a program that's well-formed and well-behaved
for both C and C++, right?

Yes, that can be done. Below, I quote Jeremy Dilatush's "Hello world"
program, which is (almost!) legal as C, as TCL, as Perl, and as a shell
script.

I am not sure which side of the argument, if any, this program supports!

#define NAME hello.c
#define DESCRIP many languages at once (tcl, perl 4 & 5, sh, C)
#define AUTHOR Jeremy Dilatush
#define DATE 7/31/96
#define dummy \
eval qq[qq? 2> /dev/null
#if 0
#\
echo 'Hello world!'; exit 0 # shell part
puts "Hello world!"; exit 0
#endif

/* C part */

#include <stdio.h>

int main(void)
{
printf ("Hello world!\n");
return 0;
}

#define dummy2(perl) \
?]; print "Hello world!\n"; exit 0 # perl part

That's almost like turning hamburger into cow. ;)

LR
 

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,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top