C/C++ guidelines

R

Richard Heathfield

LR said:
Phlip wrote:


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;
}

That is certainly valid C (and AFAIK it's valid C++ too), but in C the
following is better style:

int main(void) {
return 0;
}

(I have resisted the temptation to fiddle with brace placement and
tabulation.)

This is also legal C++, but my understanding is that in C++ it is *your*
version that is better style.
And so the answer would be yes. Right?

I think the real answer is "yes, *but*..." :)
 
P

Phlip

LR said:
I'm not sure how that follows.

This thread is experiencing a contest bragging how Standard compliant
everyone is. "K&R C is incompatible with TR2 because..." blah blah blah.

Writing such a program is rather easy if you only do simple things and avoid
each other languages' keywords...

(Not "K&R C" - that's a joke!)
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?

int main(void), unless someone clobbers me for that one... (-;
 
K

Keith Thompson

Old Wolf 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").

I think there's some confusion here between
the common subset of C90 and C99
and
the common subset of C and C++.

Incidentally, "intersection" is a perfectly good word for what we're
calling "common subset".
 
K

Keith Thompson

Jerry Coffin said:
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.
Agreed.

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).

But how good is C++ standard compliance? I've worked on a large chunk
of C++ code that had to limit its use of C++ features because, though
all the platforms on which it needed to run had C++ compilers, they
didn't all implement the full language.

Since this is cross-posted to comp.lang.c and comp.lang.c++, I won't
comment further; I really don't want to start a C vs. C++ flame war.
 
I

Ian Collins

Keith said:
But how good is C++ standard compliance? I've worked on a large chunk
of C++ code that had to limit its use of C++ features because, though
all the platforms on which it needed to run had C++ compilers, they
didn't all implement the full language.
The short answer is a lot better than C99 standard compliance!
 
K

Keith Thompson

Ian Collins said:
The short answer is a lot better than C99 standard compliance!

Sure, but in this context (maximizing portability), the relevant
question is how it compares to C90 compliance.
 
I

Ian Collins

Keith said:
Sure, but in this context (maximizing portability), the relevant
question is how it compares to C90 compliance.
Surprising close, given the complexity of the language. The complexity
does lead to differing set of bugs, but these are getting smaller all
the time. Standards conformance is partly driven by the widely used
boot library, which pushes the limits of most compilers.
 
K

Keith Thompson

Ian Collins said:
Surprising close, given the complexity of the language. The complexity
does lead to differing set of bugs, but these are getting smaller all
the time. Standards conformance is partly driven by the widely used
boot library, which pushes the limits of most compilers.

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

Did you mean "boost"?

Sounds like we need a widely used library that depends on C99.
 
J

James Kanze

Last I heard no compiler actually implements the C++ Standards.

Last I heard, Comeau implemented it, and has for some years now.
If so, by that logic, no true C++ program has ever been
written!

In a certain sense, there is no C++ compiler that is 100%
conform. Nor any C compiler which is 100% conform to C90. Nor
any compiler which is 100% conform to any standard. Compilers
are relatively complex programs, and none that I've used has
been totally without errors. And some of those errors end up by
making it reject conformant programs, or generate wrong code for
them.

In practice, specifying conformance in this was is useless. I
tend to accept a compiler as conform if 1) it has conciously
attempted to implement everything in a conformant manner, and 2)
it treats any non-conformaty which is detected as an error, to
be corrected as soon as possible. In other words, if it
considers the standard as part of its contract with its users.
Comeau definitely does (and I seem to recall hearing that the
Intel compiler does as well).

Of course, with all compilers (including Comeau), conformance
depends on the invocation options, and I'm sure that there are
options which render Comeau non-conformant as well.
 
J

James Kanze

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

#ifdef __cplusplus
#include <iostream>

int
main()
{
std::cout << "Hello, world!" << std::endl ;
return 0 ;
}
#else
#include <stdio.h>

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

:)

Seriously, the #else part of the #ifdef is also 100% conformant
C++.

Replace "program" with "useful program" in your statement, and
I'm not so sure.

And since we're talking about writing code which is portable to
several different languages... The program at
http://www.ioccc.org/1986/applin.c is portable to (K&R) C,
Fortran and the Bourne shell. (It won't work with modern C or
C++, because it uses implicit int.)
 
D

Default User

Keith said:
I think there's some confusion here between
the common subset of C90 and C99
and
the common subset of C and C++.

Incidentally, "intersection" is a perfectly good word for what we're
calling "common subset".

I think it's vanishingly rare that anyone has seriously suggested any
such thing on either newsgroup (Old Wolf didn't say which he meant by
"this NG").




Brian
 
J

James Kanze

[...]
Note this implies the requirement is "portability between platforms X and
Y". If the requirement is, instead, "port to some platform that the boss
might someday need", I must reject the requirement as untestable. Whoever
required that is responsible for picking platforms X and Y, now, or dropping
this silly requirement.

I don't think it's that black and white. A lot of requirements
are very untestable, for different reasons. How do you test a
requirement that the program be "easy for a non-technical person
to use"?

Guaranteeing portability to any platform which might possibly be
invented in the future (or might have existed in the past) is
obviously impossible, if for no other reason that you can't
possibly know what bugs some future compiler might have, and
work around them. Coding so that porting to a 64 bit platform
(even if you only have access to a 32 bit one today) or to a big
endian platform (even if you currently only have PC's) should
not cause too many problems, by avoiding code that depend on the
size of a long or the order of bytes isn't too difficult,
however. (I'd argue that well written code will do this
automatically.) Careful code review should be able to produce
the closest thing you can get to a guarantee that it will work.
(But of course, you're still not protected from the 64 bit
compiler having some new bug.)

In sum, portability isn't a yes/no question; it's a more/less
question. Code is more or less portable. And you can avoid
known portability problems (like depending on byte order) even
if you don't have access to other machines. (Although,
obviously, if you can test in the other environment, it's
better.)
 
R

Richard Tobin

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.
[/QUOTE]
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."

But are these "pre-standard" compilers? Or just non-standard compilers?

-- Richard
 
J

James Kanze

Keith Thompson wrote:
The short answer is a lot better than C99 standard compliance!

I'm not sure.

More to the point, I think that there is a difference in the
effects of the non-compliance. Almost all C compilers do
implement C90, and C99 is more or less upwards compatible, so
the only problem with non-compliance is that certain features
are missing. In the case of C++, the standard changes a number
of things with regards to what was the de facto standard before:
name lookup is different (especially in templates, for example),
so you actually have to contend with programs which compile with
pre-standard compilers, but have different semantics.
 
J

James Kanze

Thanks that was awesomely correct.
Now notice how my advice - actually become demonstrably
portable as early as your first lines of code - was
essentially the same.

Not really. It's possible to evaluate how much avoiding byte
order dependencies will cost, and decide whether it's worth it
or not, even without having access to a big-endian machine to
test your code. (That's probably a poor example: since avoiding
byte order dependencies is generally a good coding practice,
doing so will probably result in less cost in the long run.)
Crew: Can we have a Sharp Zaurus to run our unit tests on
early and often?
Boss: No!
Crew: Okay; you don't mean obsessively portable, you just
mean generally portable. Gotcha!

I think you missed his point. "Maximum portability" is not
measurable. You cannot, by any means, determine whether a given
program has the quality or not. You can, however, define
certain criteria, such as not depending on the size of a long,
or byte order, or the representation of a float, and measure
whether the program conforms to these requirements or not, and
how much adding such a requirement costs. ("Generally portable"
is no more measureable than "maximum portability".)
 
E

Eagle

Hello Robbie,

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++.

Choose your definitions wisely and they may serve you well.
Can anyone suggest any good documents that might help us? Lists of
gotchas to avoid, that sort of thing?

Develop under as many platforms as possible to see the effects of
any problems early. I often use the same methods and it has served
me well.

David
 
P

Phlip

:) wrote:

#ifdef __cplusplus
#include <iostream>

int
main()
{
std::cout << "Hello, world!" << std::endl ;
return 0 ;
}
#else
#include <stdio.h>

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

Yes, we all know the #include <stdio.h> is on C++'s shit-list.

Portability is about real-world compilers, not arbitrary Standard(s)
compilance. The #else block is well-formed C++ too, so a trivially useful
subset of C and C++ is feasible.
 
A

Army1987

You also need to check for __STDC__ being defined as something other
than 1. Some compilers have used __STDC__==0 to indicate partial
compliance.
Usually, #ifndef __STDC__ is (was) used to check whether features
introduced in ANSI C89 not present in K&R C (e.g. ## token-pasting
operator) are available. A compiler which *does* define __STDC__
but to something other than 1 is very likely to have them.
 
A

Army1987

Replace "program" with "useful program" in your statement, and
I'm not so sure.
You can. Cast every void * to be implicitly converted. In case
this ever made a difference, cast characters constant to int. If
you need to take the address of main() for any reason (including
calling it recursively), rename it mymain() and add
int main(int argc, char *argv[]) { return mymain(argc, argv); }
and so on... This won't cause any useful program to become less
useful. But it cause a decent program to become terribly ugly.
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top