Most crucial elements in a light-weight C++ coding

2019-01-20 22:29发布

I've been involved in developing coding standards which were quite elaborate. My own experience is that it was hard to enforce if you don't have proper processes to maintain it and strategies to uphold it.

Now I'm working in, and leading, an environment even less probable to have processes and follow-up strategies in quite a while. Still I want to uphold some minimum level of respectable code. So I thought I would get good suggestions here, and we might together produce a reasonable light-weight subset of the most important coding standard practices for others to use as reference.

So, to emphasize the essence here:

What elements of a C++ coding standard are the most crucial to uphold?

  • Answering/voting rules

    • 1 candidate per answer, preferably with a brief motivation.

    • Vote down candidates which focuses on style and subjective formatting guidelines. This is not to indicate them as unimportant, only that they are less relevant in this context.

    • Vote down candidates focusing on how to comment/document code. This is a larger subject which might even deserve its own post.

    • Vote up candidates that clearly facilitates safer code, which minimizes the risk of enigmatic bugs, which increases maintainability, etc.

    • Don't cast your vote in any direction on candidates you are uncertain about. Even if they sound reasonable and smart, or on the contrary "something surely nobody would use", your vote should be based on clear understanding and experience.

30条回答
forever°为你锁心
2楼-- · 2019-01-20 23:11

Beware of C API

The C API can be very efficient, but will need exposed raw data (i.e. pointers, etc.), which won't help the safety of the code. Use existing C++ API instead, or encapsulate the C API with C++ code.

e.g.:

// char * d, * s ;
strcpy(d, s) ; // BAD

// std::string d, s ;
d = s ;        // GOOD

Never use strtok

strtok is not reentrant. Which means that if one strtok is started while another is not ended, one will corrupt the "internal data" of the other.

How it clearly facilitates safer code, which minimizes the risk of enigmatic bugs, which increases maintainability, etc.?

Using C API means using raw types, which can lead to interesting bugs like buffer overflow (and potential stack corruption) when a sprintf goes too far (or string cropping when using snprintf, which is a kind of data corruption). Even when working on raw data, malloc can be easily abused, as shown by the following code:

int * i = (int *) malloc(25) ; // Now, I BELIEVE I have an array of 25 ints!
int * j = new int[25] ;        // Now, I KNOW I have an array of 25 ints!

Etc. etc..

As for strtok: C and C++ are stack-enabled languages, that enable to user to not care about what functions are above his own on the stack, and what functions will be called below his own on the stack. strtok removes this freedom of "not caring"

查看更多
放我归山
3楼-- · 2019-01-20 23:12

Principle of least surprise.

Maybe it's not the "flavor" of rules you are looking for, but I'd definitely put it first.

It is not only the root, reason and sanity check for all the boring stuff like formatting and commenting guidelines, but - to me more importantly - puts the emphasis on the code being read and understood, rather than just compiled.

It also covers the only reasonable code quality measure I have ever encountered - WTF's per minute.

I'd use that first point to stress the importance and value of clear, consistent code, and to motivate the following items in the coding standard.

查看更多
手持菜刀,她持情操
4楼-- · 2019-01-20 23:12

If the toolchain in use (or projected use) has an inefficient implementation of exceptions, it might be wise to avoid their use. I've worked under such conditions.

Update: here is someone else's rationale for "Embedded C++", which seems to exclude exceptions. It makes the following points:

  • It is difficult to estimate the time between when an exception has occurred and control has passed to a corresponding exception handler.
  • It is difficult to estimate memory consumption for exception handling.

There is more elaborate text on that page, I didn't want to copy it all. Plus, it's 10 years old so it might be of no use any longer, which is why I included the part about the toolchain. Perhaps that should also read "if memory is not considered a major problem", and/or "if predictable real-time response is not required", and so on.

查看更多
Anthone
5楼-- · 2019-01-20 23:12

Public inheritance must model The Liskov Substitution Principle (LSP).

Code reuse/import without substituability must be implemented with private inheritance when a very strong coupling makes sense, or with aggregation otherwise.

查看更多
戒情不戒烟
6楼-- · 2019-01-20 23:13

Use references instead of pointers where possible. This prevents constant defensive NULL checks.

查看更多
▲ chillily
7楼-- · 2019-01-20 23:13

A point should be dedicated to explain the difference between value semantics and entity semantics. It could provide the typical code snippets about how copy is handled is the various cases.

See also Checklist for writing copy constuctor and assignment operator in C++

查看更多
登录 后发表回答