Prev: Lifetime of a temporary bound to a reference
Next: When I convert "0.0003" and "3.e-4" in VC++ they are the same
From: Alf P. Steinbach /Usenet on 29 Jun 2010 17:14 * 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 29 Jun 2010 21:41 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 29 Jun 2010 22:01 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 30 Jun 2010 23:27 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 30 Jun 2010 23:26
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! ] |