C++ Coding Standards

J

jacob navia

Michael Mair a écrit :
(e-mail address removed) schrieb:
<snip: cn-URL advertising a translated version of "C++ Coding Standards"
and an excerpt of the list of rules>

While Herb and Andrei have done excellent work and the book
can serve as company C++ coding guideline or standard or
provide a good base for one, this has to do nothing whatsoever
with C. In fact, some of the more detailled rules do not make
sense or may even be harmful when applied to C.

Cheers
Michael

Most of those rules apply to C too. The ones that are C++ specific are:
38 (initialization dependencies).
This is for C++ constructors stuff. Mostly irrelevant in C.
30 (Avoid macros).
In standard C is not possible to replace
#define MAX_SIZE 512
with
const int MAX_SIZE=512;
Lcc-win32 will accept the C++ semantics when you write
static const int MAX_SIZE=512;
In a C context I need the static to ensure the variable is
not accessed anywhere else. In this particular case lcc-win32
will just replace all occurrences of MAX_SIZE with 512
as it was a macro.
28 Use const proactively.
C++ "const" stuff is obscure and can be ignored in C. I
think this simplifies the language, at least it produces
less headaches to me :)
21 (Ensure resources are owned by objects).
C is not object oriented, so this makes no sense, since
no destructors exists.

The other rules are quite sensible
Organizational and Policy Issues
1
0. Don't sweat the small stuff. (Or: Know what not to standardize.)
2
1. Compile cleanly at high warning levels.
4
2. Use an automated build system.
7
3. Use a version control system.
8
4. Invest in code reviews.
9

All of those rules make sense in C, Python, Ada, Visual Basic...
They are just common sense.

Design Style
11
5. Give one entity one cohesive responsibility

I am not sure what this means in C, probably that you have one function
that organizes the software module calling the others, managing the
shared data, etc.

This is too abstract to be of any use.

12
6. Correctness, simplicity, and clarity come first
13
7. Know when and how to code for scalability.
14
8. Don't optimize prematurely.
16
9. Don't pessimize prematurely.
18
10. Minimize global and shared data.
19
11. Hide information.
20
12. Know when and how to code for concurrency.

Ditto, they are just common sense.

Coding Style
27
14. Prefer compile- and link-time errors to run-time errors.

Who would discuss this? The whole problem is that sometimes it is
just not possible to do!
32
17. Avoid magic numbers.
34
18. Declare variables as locally as possible.

C99 allows you to define variables just besides their intended
usage so this applies to C too.

35
19. Always initialize variables.
36
20. Avoid long functions. Avoid deep nesting.
40
23. Make header files self-sufficient.
42
24. Always write internal #include guards. Never write external
#include guards.


Internal guards (if I understood correctly) would be this:

File win.h

#ifndef __win_h__
#define __win_h__
/* The rest of the win.h comes here */
#endif

External guards would be:
#ifndef __win_h__
#define __win_h__
#include <win.h>
#endif

This is OK, and I would agree with the rule, but I use sometimes

#ifndef __win_h__
#include <win.h>
#endif

This spares the preprocessor to open a file, and parse the whole
file...
I use more often the

#pragma once

that lcc-win32 provides to avoid all this guards stuff, and that
should be standardized as common practice. Microsoft uses the
same construct.

All in all an interesting message in this group. At last, a message
that tells something substantive
 
C

ct-86

http://www.cdbook.cn/book.asp?id=2393
Organizational and Policy Issues
1
0. Don't sweat the small stuff. (Or: Know what not to standardize.)
2
1. Compile cleanly at high warning levels.
4
2. Use an automated build system.
7
3. Use a version control system.
8
4. Invest in code reviews.
9

Design Style
11
5. Give one entity one cohesive responsibility
12
6. Correctness, simplicity, and clarity come first
13
7. Know when and how to code for scalability.
14
8. Don't optimize prematurely.
16
9. Don't pessimize prematurely.
18
10. Minimize global and shared data.
19
11. Hide information.
20
12. Know when and how to code for concurrency.
21
13. Ensure resources are owned by objects. Use explicit RAII and
smart pointers. 24

Coding Style
27
14. Prefer compile- and link-time errors to run-time errors.
28
15. Use const proactively.
30
16. Avoid macros.
32
17. Avoid magic numbers.
34
18. Declare variables as locally as possible.
35
19. Always initialize variables.
36
20. Avoid long functions. Avoid deep nesting.
38
21. Avoid initialization dependencies across compilation units.
39
22. Minimize definitional dependencies. Avoid cyclic dependencies.
40
23. Make header files self-sufficient.
42
24. Always write internal #include guards. Never write external
#include guards. 43
http://www.cdbook.cn/book.asp?id=2393
 
M

Michael Mair

(e-mail address removed) schrieb:
<snip: cn-URL advertising a translated version of "C++ Coding Standards"
and an excerpt of the list of rules>

While Herb and Andrei have done excellent work and the book
can serve as company C++ coding guideline or standard or
provide a good base for one, this has to do nothing whatsoever
with C. In fact, some of the more detailled rules do not make
sense or may even be harmful when applied to C.

Cheers
Michael
 
M

Michael Mair

jacob said:
Michael Mair a écrit :

Most of those rules apply to C too.

The general "short rule", yes, but what they are actually writing
as full rule, explanation and examples does not necessarily apply
to C. However, these are the _flesh_ of the respective rule.
The ones that are C++ specific are:
38 (initialization dependencies).
This is for C++ constructors stuff. Mostly irrelevant in C.
30 (Avoid macros).
In standard C is not possible to replace
#define MAX_SIZE 512
with
const int MAX_SIZE=512;
28 Use const proactively.
C++ "const" stuff is obscure and can be ignored in C. I
think this simplifies the language, at least it produces
less headaches to me :)

I think this is a basic decision; you can still decide to
use const where necessary, wherever sensible or wherever possible
(e.g. apply const to all parameters to ensure that they are not
abused as auxiliary variables or stuff like that).
It makes sense to "const" early and consistently; especially when
dealing with third party libraries, you may run into problems.
21 (Ensure resources are owned by objects).
C is not object oriented, so this makes no sense, since
no destructors exists.


I am snipping the useless page numbers in the following.
The other rules are quite sensible
Organizational and Policy Issues
0. Don't sweat the small stuff. (Or: Know what not to standardize.)
1. Compile cleanly at high warning levels.
2. Use an automated build system.
3. Use a version control system.
4. Invest in code reviews.

All of those rules make sense in C, Python, Ada, Visual Basic...
They are just common sense.
Agreed.

Design Style
5. Give one entity one cohesive responsibility

I am not sure what this means in C, probably that you have one function
that organizes the software module calling the others, managing the
shared data, etc.

This is too abstract to be of any use.

No, this can make perfect sense depending on what you do.
In the simplest case, you make sure that one "basic" function
does exactly one thing without semantic side effects.
Example:
A function called sortEntries() should not change the "entries".

Whenever you build more complex functionality, you build it
from other functions. This goes quite nicely with some of the
following rules.
6. Correctness, simplicity, and clarity come first
7. Know when and how to code for scalability.
8. Don't optimize prematurely.
9. Don't pessimize prematurely.

As I do not have the book here at the moment, I can only go by
memory.
AFAIR, this is one of the cases I meant: What they are writing
there as examples has no relevance for C and may even pessimize
for some very basic compilers for embedded chips.
10. Minimize global and shared data.
11. Hide information.
12. Know when and how to code for concurrency.

Ditto, they are just common sense.

Coding Style
14. Prefer compile- and link-time errors to run-time errors.

Who would discuss this? The whole problem is that sometimes it is
just not possible to do!

There are enough people, especially among "Windows C/C++" crowd,
who are not aware of this and use run-time checks at each and
every corner -- and the programmes die ungracefully as the number
of checks makes sensible error handling virtually impossible.

As for what is possible: You can test some of the basic assumptions
(CHAR_BIT == 8, the used *intN* typedefs really map to 2s complement
exact width types with the required widths, ...) at compile time,
which many people don't do.
17. Avoid magic numbers.
18. Declare variables as locally as possible.

C99 allows you to define variables just besides their intended
usage so this applies to C too.

It even applies to C89 -- nobody hinders you to use a compound
statement; this can be interesting if you have conditionally
compiled code parts.
19. Always initialize variables.
20. Avoid long functions. Avoid deep nesting.
23. Make header files self-sufficient.
24. Always write internal #include guards. Never write external
#include guards.

Internal guards (if I understood correctly) would be this:

File win.h

#ifndef __win_h__
#define __win_h__
/* The rest of the win.h comes here */
#endif

Yes, but do not use leading underscores for your own macro
identifiers; I liked the H_HEADERNAME_H convention suggested by
someone in a recent thread.
External guards would be:
#ifndef __win_h__
#define __win_h__
#include <win.h>
#endif

You have understood that correctly.

This is OK, and I would agree with the rule, but I use sometimes

#ifndef __win_h__
#include <win.h>
#endif

This spares the preprocessor to open a file, and parse the whole
file...

Um, this is ugly: The header guards belong to the header _only_.
The implementor is free to change the header guard macro identifier
at will.
If you need something like that, then use a macro which is explicitly
defined only if you -- by whatever chain of includes -- have access
to the desired functionality, e.g.
#ifndef WHATEVER_INDICATOR
# include "i_provide_whatever.h"
#endif

Relying on header guard names as WHATEVER_INDICATOR is IMO dangerous
and unsafe and will often break with a new compiler, OS, library
version etc.

I am not talking about what an implementation does when providing
the standard library headers -- it is free to do whatever it likes
but if it breaks too easily, then this is a QOI matter.
I use more often the

#pragma once

that lcc-win32 provides to avoid all this guards stuff, and that
should be standardized as common practice. Microsoft uses the
same construct.

There are reasons against this; the first that comes to my mind:
Think of repeatedly included template files where you just set
macro parameters before including the template to generate the
desired code -- if the author of the including file has to change
the code to achieve the previous functionality just because
someone else included his file with #pragma once in yet another
include file included before that one, then you have broken the
code, maybe in a very subtle manner.


I wonder why you have not included all of the rules to prove
your point. I seem to remember that there were a good deal
more.


Cheers
Michael
 

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