From: Alf P. Steinbach /Usenet on
* Olve Maudal, on 28.06.2010 22:51:
> At the NDC2010 conference, I gave a presentation where I demonstrated
> Solid C++ code by example:
>
> http://www.slideshare.net/olvemaudal/solid-c-by-example
>
> It would be great to have your opinion about the examples I present.
> Is this solid code, or can it be improved even further?

* Slide 9:

Point 4 "no need to include files included by the base class declaration"
is debatable. Trying to minimize header inclusion is wasting programmer's time.
But when one has a system infested by so called complexity (a euphemism for
spaghetti, although not necessarily control flow spaghetti) then one may have
excessive build times that also waste programmer's time, and one may try to do
anything to address this very manifest and in-one's-face /symptom/, like minimal
header inclusion, forward declarations, include site include guards a la Lakos,
and say a Very Large Monitor displaying current build progress, but I think it's
a good idea to recognize that symptom treatment does not fix the underlying
causes, whereas e.g. formalized QA, and separate QA group, might.

Point 8 "importing a namespace in implementation files is usually not a good
idea". Hm. Again it is a matter of context. In a "complex" system (spaghetti)
using qualified names everywhere might reduce some symptoms and reduce time
wasted on bug-hunting. But otherwise, readability reduces programmers' time,
i.e. improves programmer efficiency. Some people do maintain that to their eyes
std::cout is more readable than cout, they swallow their colons for breakfast
every day & enjoy it. Not for me though; if one is not going to use namespaces
as they were intended, including "using", then just stick to C prefixes. :-)

Point 9, ""never" import a namespace in a header file, good advice for novices
but sometimes you really want to expose a namespace /inside/ a namespace. So
perhaps amend to "in the global namespace in a header file" and just remove
those quotes around "never". Like, never say "never".

Point 16, "avoid superfluous use of ()", well this has to do with what one's
eyes are comfortable with. I really hate it when I see "return (6*7);", hello,
what's that? But on the other hand when I see "return x > y && y > z;" then I
would like a parenthesis around that expression, "return (x > y && y > z);".
It's like my eyes don't recognize boolean expressions unless they're in
parentheses. Others' eyes may be different. So I'd say, have no rule on this!

Point 17, "prefer forward declarations where you can", is again (as I understand
it) about excessive build times for spaghetti system, treating symptoms instead
of causes. It can even be dangerous time-wasting advice, with MSVC which does
not honor the standard's equivalence for "struct" and "class" for a forward
declaration, so you risk a mystifying link error. And some people use MSVC, I
think. :-)

Point 18 "do not use explicit on multi-argument constructors", well how about T(
int, int = 1, int = 2 ). Needs a little re-wording, I think!


* Slide 10:

There was a nice version of this image, with /TeleTubbies/, floating around!
Mucho better in my humble view! Alas, a disk crash removed my only copy.


* Slide 13:

Really, there's nothing wrong with that code, on its own, except a lack of
abstraction! :-) But when you add in a later slide the information that this is
a header file, then there are some things wrong, which you point out. Slide
suffers from missing context.


* Slide 47:

The constructor argument "uint32_t ssp_flags" lacks proper typing. E.g. an enum.


* Slide 56:

"Use std::size_t when appropriate". Two things wrong with that. One, all this
visually distracting namespace qualification: just write size_t. That's even
more important with C++0x. Second, using size_t for an offset is in general just
to add complexity and ask for trouble. ptrdiff_t helps. typedef it as Size and
be done with it. ;-)


OK, now I'm not going to go through the rest since I suspect that this was about
the point when I arrived at the last Oslo C++ Users Group meeting, where you had
a Very Good Presentation of this, so I've seen the rest (I reckon).


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Seungbeom Kim on
On 2010-06-28 13:51, Olve Maudal wrote:
> At the NDC2010 conference, I gave a presentation where I demonstrated
> Solid C++ code by example:
>
> http://www.slideshare.net/olvemaudal/solid-c-by-example
>
> It would be great to have your opinion about the examples I present.
> Is this solid code, or can it be improved even further?

One thing I disagree to is the "superfluous" parentheses around the
operand of sizeof. It's perfectly legal to drop the parentheses if
the operand is an expression, and I sometime do it too, especially
in idiomatic situations and when there's no possibility of confusion,
e.g.:

char buf[...];
ssize_t n = read(fd, buf, sizeof buf);

however, confusion may arise when the operand or the expression
containing sizeof gets more complex, e.g.:

a * b * sizeof * c * d // eh?

Therefore, there are situations where it is not recommended to drop
the parentheses around the operand, even it is allowed and thus might
be regarded "superfluous".

The case is somewhat different for return statements, because it is
a statement, not an operator, and the source of confusion is far less:
everything that's between "return" and ";" has to be the expression
to be returned. As a result, more people will frown upon superfluous
parentheses in return statements than in sizeof expressions.

Another reason is consistency: sizeof(type-id) always requires
parentheses, so why impose a rule that we should use them in some
cases and should not in other cases? Just use them all the time,
and you'll get no trouble. Even though I do drop them sometimes,
I wouldn't try to "correct" someone else who uses them all the time.
(I think I've even seen some guidelines that recommend using them
all the time.)

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Seungbeom Kim on
On 2010-06-29 13:31, Hakusa(a)gmail.com wrote:
>
> I disagree with your classification of magic numbers. By what i see in
> your slide:
> f(60); // using magic number
> but:
> const int x = 60;
> f(x); // Suddenly OK.
> In my mind, 60 does not stop being magic just because it's named. The
> question of where this number came from is still unanswered.

You should name the variable appropriately. 'ssp_flags_offset' and
'challenge_offset' in the example from the OP's slides are named so,
and 'x' is not.

> Slide 171; you complain about messing with "borrowed" things. Why not
> just save the flags, then reset them?

That's another way to avoid messing with borrowed things.
As long as the client cannot tell, it's fine.

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
Nick Hounsome wrote:
> On 28 June, 21:51, Olve Maudal <olve.mau...(a)gmail.com> wrote:
>> At the NDC2010 conference, I gave a presentation where I demonstrated
>> Solid C++ code by example:
>>
>> http://www.slideshare.net/olvemaudal/solid-c-by-example
>>
>> It would be great to have your opinion about the examples I present.
>> Is this solid code, or can it be improved even further?
>
> Assuming that we are pretending someone else wrote this and we are
> reviewing it or just doing some mods on a module:
>
> I know it's not necessary but pretty much everyone I've ever met uses
> braces with sizeof and in such cases it's always best to go with
> majority taste.
>
> Even braces with return - Whoever wrote it found it more readable that
> way so I would probably, reluctantly, leave them. I certainly wouldn't
> change existing code to remove extra braces unless I was rewriting
> anyway - It's kind of rude and it doesn't help when you come to diff
> the code to see what changes were made.
I very much doubt that they use braces {} because that would not work.
Please be careful to distinguish between braces and parentheses. The
terms mean different things.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
Leigh Johnston wrote:

> I don't agree that default arguments should be avoided, the alternative is
> overloading which I think is sometimes overkill.
>
Except that using default arguments too often results in parameters
being ordered on the basis of which can be defaulted rather than which
logically comes last.

Overloading has the advantage of being a general solution so that any
parameter can be 'defaulted'. The cost is very low because the overloads
are simply inline wrappers that dispatch to the general version.

The main reason fgor using default arguments was that it reduced
problems with multiple constructors where you could not use a wrapper to
forward to the genral version. That has been fixed in C++0x and so the
largest motive for using default arguments has gone.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]