views:

564

answers:

8

Hi,

As a counterpart to C++ Coding Guideline 102, which of the 101 guidelines of Sutter & Alexandrescu do you violate or ignore most often, and why?

+5  A: 

I'd say for me, it's probably 16. Avoid macros. I find there are a good number of things I can only do with macros (especially inlining __FILE__ and __LINE__ into expressions), and many cases where I need a compact expression which operates in the external function context (checking result codes and returning, for example). As a result, my code tends to be sprinkled liberally with assertions in the form of macros, for example, so I'd say this is one I ignore quite a bit.

That said, I would forgo most of my uses if the language allowed alternative similarly compact expressions of the same concepts, but since it does not, macros will be around for a long time.

I should add, it's not to say that I think the suggestion is bad, or it's bad to follow it when you have an alternative available. I just find that I end up using a lot of macros, usually because there's no alternative available.

Nick
Good point, though I usually avoid macros, there certainly are some reasonable uses for them.
Evan Teran
The thing is, "avoid" isn't the same as "don't ever use". Having no better alternative sounds like a good enough explanation to use them while abiding the guideline.
JB
+2  A: 

To be honest, I have naturally over time developed habits which match these guidlines almost perfectly. Following these types of coding standards leads to clean, easy to maintain code.

Evan Teran
+2  A: 

No. 56 - Use vector by default. I often use a deque instead. Interestingly, Herb Sutter appears to be conflicted on this himself.

Fred Larson
+5  A: 

I broke 19 (always initialize variables) on this site only yesterday. My code snippet was:

uint64_t i = getIEEEbitpatternByMeansRelevantToTheQuestion();
double d;
memcpy(&d, &i, 8);

Can't see any point in initializing d: there is no value which could possibly be meaningful, and the compiler will either ignore the value I do provide or else do something wasteful with it.

Initializing non-POD types, and POD types which are members of classes, is eminently sensible. Initializing something just to memcpy/memset over it, not so much.

In fact, one of the reasons for initializing non-PODs is to avoid a default construction that you just assign over the top of later. Initializing a POD that you're planning to scribble over is basically the same bad thing.

I don't have the book, though, so it could be that's what they mean and the "always" in the title is misleading.

Steve Jessop
But you did initialize d - you just used memcpy to initialize it!
Michael Kohne
You could do: double d = *((double *) instead. No need to use memcpy at all.
Skizz
+2  A: 

I like a good c-style cast now and then, I'm afraid to admit. (I realize the problems with it - just can't help myself)

JimDaniel
+1  A: 

I ignore most of them, because they can be summarized as: use C++ as if it were a high-level object-oriented language. But if you want a high-level object-oriented language, there are much better candidates (C#, Java, Lisp, Python etc). C++ is essentially the mother of all structured macro assemblers, and I use it as such, and only in jobs where that is what is required.

rwallace
Er, sounds like you're thinking of C, rather than C++.
jalf
Well, I'm thinking of C++ rather than Java-- ;)
rwallace
A: 

After having a look at all the rules, it would be: 89. Write function objects correctly. I never take the time to write them correctly. Sometimes I use variadic functions, but it is not exactly a choice I have.

Luc Hermitte
+1  A: 

72. Prefer to use exceptions to report errors.

Instead, I use 72-ALT. Don't throw exceptions. :)

Ok, except for reporting caller's precondition violations in the public API layer of a published code library - and in that layer only.

Daniel Daranas