Monday, January 6, 2014

FeedaMail: Comments for Sutter’s Mill

feedamail.com Comments for Sutter's Mill

Comment on GotW #7c: Minimizing Compile-Time Dependencies, Part 3 by Loïc Joly

@Roman “- we have absolutely _no_ tool support, so a developer have to _guess_ which header has greatest impact and is worth her time;”

There is a tool whose puspose is to automate someway header files removal: http://code.google.com/p/include-what-you-use/ I’ve not used it myself, so I cannot say how good I think it is. It has some quite complex heuristics to select which files should be included, and which fiels should not (it does not try to get to the absolute minimal). This article describes some of them: http://code.google.com/p/include-what-you-use/wiki/WhyIWYUIsDifficult.

Read More »

Comment on GotW #7c: Minimizing Compile-Time Dependencies, Part 3 by Roman M.

@Jussi: nice script you have there! I am not aware of something similar Visual C++. Unfortunately your blog-post didn’t reveal whether good compilation throughput is due to PIMPL or just because those CPPs define base classes and naturally have no or small dependencies. the mere fact of such big compile throughput variation in diverse projects suggests that solving compile time issues is hard. Your measurement, while offering interesting insights, lacks information where is make sense to introduce Pimpl – the closer to class hierarchy root we get, the bigger impact can be expected. One would need some kind of directed header include graph weighted by compilation time of corresponding CPP.

On the side note: in my projects about 60% of build time is spent by the linker, but thats another story ;)

Read More »

Comment on GotW #7b Solution: Minimizing Compile-Time Dependencies, Part 2 by mttpd

@Herb: regarding the using-directive — unless we’re talking about strictly scoped uses (e.g., within a function scope; but not within (still dangerous) namespace level), with time I’m becoming less and less inclined to agree with this. If anything, nowadays I find myself more inclined toward using-declaration — and even that only under extremely limited, specific circumstances (i.e., strictly for the idiomatic ADL pull-in technique: as in std::swap, std::begin, std::end, etc.).

I’m talking here not solely from the legalistic perspective (“what is legal” / allowed by the standard — sure, no problems here), but also from the good software engineering principles perspective (what is right/maintainable/extensible — and I do see some problems here; let me know what you think about these).

For instance, we all agree that it has no place in the header files. However, if we do, then this itself has implications that (IMHO) go further:

1. Readability — this may vary depending on a domain, etc., I’m a heavy user of Boost libraries, which use the same naming convention as the C++ Standard Library. In practice, symbol named “vector” may correspond to around dozen different names (and it’s not unusual at all to use standard C++ vector, Boost.MPL vector and, say, Boost.uBLAS vector, in one codebase). A single misplaced using-directive will make name clashes unavoidable and not always trivial to track down (diagnostic messages for this can be “funny” at times).

Yes, I’m very careful about coming up with distinct, maximally self-explanatory variable (and typedefs!) names (some would perhaps say to the point of being obsessive about it), yes, the context helps, no, I don’t think that’s enough (especially given that programming is primarily a social activity and we have to take into account that other team members coming from different domains may find different contexts “obvious” — and other “arcane”).

If taken to extreme, this may imply having to define (sub)library-specific prefixed names, as in pre-namespaces Qt (e.g., QVector) — isn’t that a problem that namespaces are precisely aiming to solve?

2. Complexity — effectively, encouraging using-directive for implementation files amounts to encouraging to have two different naming conventions for cpp and hpp/ipp files — multiple naming conventions raise overall coding style complexity, while one naming convention brings the advantage of a consistent, uniform style that can be used throughout the entire team/organization (independently of member/team-specific domains).

3. Maintenance & refactoring — again, maintaining different naming conventions for cpp and hpp/ipp files means having to change (rename) the unqualified names each time we’re moving code from implementation (or specific application) to the interface (or general library); this makes the code less refactoring-friendly (again, YMMV, but another reason I may be biased here is that I routinely see “write a reusable library” as the preferred way to solve programming problems; anything that distracts from this ultimately does more harm than good).

I do recall Item 59 stating “which would be onerous, and frankly people just won’t put up with it.” However, it seems that (mostly) header-only libraries, like Boost, have empirically demonstrated that people do put up with it after all. Yes, it is a few extra keystrokes, but personally I find the using-directive readability, complexity, maintenance, and refactoring costs to be more onerous. Given that most code is read/maintained more often that it’s written from the scratch, isn’t optimizing the no. of keystrokes a classic case of premature optimization (on the suboptimal metric at that)?

Let me know if I’m wrong, perhaps I am missing something?

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Herb Sutter

@PP: Fixed, thanks.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by PP

Not sure where to send this, so feel free to remove this comment! There is a typo in: CHAR_BITS*izeof(int)-1

Read More »

Comment on GotW #7b Solution: Minimizing Compile-Time Dependencies, Part 2 by Ralph Tandetzky

@mttpd In most of my production code I don’t use using namespace. However, sometimes I do and I find my code more readable because of it. Examples are using namespace std::chrono or some Boost namespaces which are tedious to spell out all the time. Sometimes it is idiomatic to write

  using namespace std;  swap( x, y );  

or similar code as you already noted yourself. Name clashes can be avoided because it’s YOUR code and you can change it if it becomes necessary. I don’t believe it makes sense to produce another guideline to avoid using namespace in cpp files. Sometimes it is better to do so, sometimes it is not. Use your programmer gut feeling and don’t sweat the small stuff. After all it’s a matter of taste.

Read More »

Comment on GotW #7c: Minimizing Compile-Time Dependencies, Part 3 by Klimax

@Roman M:
Timing can be enabled by setting:
Tools->Options->Projects and Solutions->VC++ Project Settings->Build Timing
(IIRC at least since VS 2010, but might be even earlier)

Output looks like

  12>Project Performance Summary:  12>    326932 ms  C:\Dan\Klimax-tools\tools\net\EmuleMorphXT\MorphXT\emule100.vcxproj   1 calls  12>              326932 ms  Rebuild                                    1 calls    12>Target Performance Summary:  12>        0 ms  AfterRebuild                               1 calls  12>        0 ms  ResolveReferences                          1 calls  12>        0 ms  SelectClCompile                            1 calls  12>        0 ms  _CheckForCompileOutputs                    1 calls  12>        0 ms  GetResolvedWinMD                           1 calls  12>        0 ms  CleanPublishFolder                         1 calls  12>        0 ms  CleanReferencedProjects                    1 calls  12>        0 ms  _PrepareForBuild                           1 calls  12>        0 ms  _Midl                                      1 calls  12>        0 ms  BuildCompile                               1 calls  12>        0 ms  ComputeManifestGeneratedLinkerInputs       1 calls  12>        0 ms  BeforeClean                                1 calls  12>        0 ms  CreateCustomManifestResourceNames          1 calls  12>        0 ms  AfterCppClean                              1 calls  12>        0 ms  BeforeLink                                 1 calls  12>        0 ms  AfterBuild                                 1 calls  12>        0 ms  AfterBuildCompileEvent                     1 calls  12>        0 ms  _BuildLinkAction                           1 calls  12>        0 ms  BeforeResourceCompile                      1 calls  12>        0 ms  AfterMidl                                  1 calls  12>        0 ms  PreLinkEvent                               1 calls  12>        0 ms  _ClCompile                                 1 calls  12>        0 ms  AfterClean                                 1 calls  12>        0 ms  SelectCustomBuild                          1 calls  12>        0 ms  AfterClCompile                             1 calls  12>        0 ms  _CopySourceItemsToOutputDirectory          1 calls  12>        0 ms  AfterResourceCompile                       1 calls  12>        0 ms  ComputeCustomBuildOutput                   1 calls  12>        0 ms  _Xsd                                       1 calls  12>        0 ms  AfterBuildGenerateSources                  1 calls  12>        0 ms  Rebuild                                    1 calls  12>        0 ms  MakeDirsForBscMake                         1 calls  12>        0 ms  BeforeRebuild                              1 calls  12>        0 ms  MakeDirsForResourceCompile                 1 calls  12>        0 ms  _ResourceCompile                           1 calls  12>        0 ms  ComputeLinkInputsFromProject               1 calls  12>        0 ms  BeforeCppClean                             1 calls  12>        0 ms  _Link                                      1 calls  12>        0 ms  BuildLinkTraverse                          1 calls  12>        0 ms  PrepareForRun                              1 calls  12>        0 ms  _XdcMake                                   1 calls  12>        0 ms  CreateSatelliteAssemblies                  1 calls  12>        0 ms  MakeDirsForManifest                        1 calls  12>        0 ms  SelectResourceCompile                      1 calls  12>        0 ms  ExpandSDKReferences                        1 calls  12>        0 ms  BuildCompileTraverse                       1 calls  12>        0 ms  _GenerateSatelliteAssemblyInputs           1 calls  12>        0 ms  _Deploy                                    1 calls  12>        0 ms  ComputeMIDLGeneratedCompileInputs          1 calls  12>        0 ms  CppClean                                   1 calls  12>        0 ms  PrepareResourceNames                       1 calls  12>        0 ms  AfterBuildGenerateSourcesEvent             1 calls  12>        0 ms  _SplitProjectReferencesByFileExistence     1 calls  12>        0 ms  BeforeClCompile                            1 calls  12>        0 ms  _SelectedFiles                             1 calls  12>        0 ms  AfterResolveReferences                     1 calls  12>        0 ms  BeforeResolveReferences                    1 calls  12>        0 ms  AfterLink                                  1 calls  12>        0 ms  _ALink                                     1 calls  12>        0 ms  PreBuildEvent                              1 calls  12>        0 ms  MakeDirsForMidl                            1 calls  12>        0 ms  _BscMake                                   1 calls  12>        0 ms  ResolveSDKReferences                       1 calls  12>        0 ms  _BuildGenerateSourcesAction                1 calls  12>        0 ms  _Appverifier                               1 calls  12>        0 ms  ComputeMASMOutput                          1 calls  12>        0 ms  Clean                                      1 calls  12>        0 ms  ComputeRCGeneratedLinkInputs               1 calls  12>        0 ms  BuildGenerateSourcesTraverse               1 calls  12>        0 ms  MakeDirsForXdcMake                         1 calls  12>        0 ms  Build                                      1 calls  12>        0 ms  BeforeBuildGenerateSources                 1 calls  12>        0 ms  ResolvedXDCMake                            1 calls  12>        0 ms  _PrepareForRebuild                         1 calls  12>        0 ms  GetInstalledSDKLocations                   1 calls  12>        0 ms  _BuildCompileAction                        1 calls  12>        0 ms  BuildLink                                  1 calls  12>        0 ms  ComputeLegacyManifestEmbedding             1 calls  12>        0 ms  BuildGenerateSources                       1 calls  12>        1 ms  PGInstrumentedClean                        1 calls  12>        1 ms  ResolveAssemblyReferences                  1 calls  12>        1 ms  CoreClean                                  1 calls  12>        1 ms  ComputeLinkSwitches                        1 calls  12>        1 ms  FinalizeBuildStatus                        1 calls  12>        1 ms  CopyFilesToOutputDirectory                 1 calls  12>        1 ms  AssignProjectConfiguration                 1 calls  12>        1 ms  ComputeRCOutputs                           1 calls  12>        1 ms  ResolveProjectReferences                   1 calls  12>        1 ms  ComputeReferenceCLInput                    1 calls  12>        1 ms  ComputeCLCompileGeneratedSbrFiles          1 calls  12>        1 ms  GetCopyToOutputDirectoryXamlAppDefs        1 calls  12>        1 ms  _PrepareForClean                           1 calls  12>        1 ms  _CheckForInvalidConfigurationAndPlatform   1 calls  12>        1 ms  ComputeManifestInputsTargets               1 calls  12>        1 ms  GetFrameworkPaths                          1 calls  12>        1 ms  GetReferenceAssemblyPaths                  1 calls  12>        1 ms  GetCopyToOutputDirectoryItems              1 calls  12>        1 ms  PlatformPrepareForBuild                    1 calls  12>        1 ms  SplitResourcesByCulture                    1 calls  12>        2 ms  _PrepareForReferenceResolution             1 calls  12>        2 ms  MakeDirsForCl                              1 calls  12>        2 ms  ComputeCLInputPDBName                      1 calls  12>        2 ms  DoLinkOutputFilesMatch                     1 calls  12>        2 ms  MakeDirsForLink                            1 calls  12>        3 ms  ComputeCLGeneratedLinkInputs               1 calls  12>        3 ms  ComputeCLCompileGeneratedXDCFiles          1 calls  12>        3 ms  CheckInstalledVCLibsIPP                    1 calls  12>        3 ms  SetBuildDefaultEnvironmentVariables        1 calls  12>        3 ms  InitializeBuildStatus                      1 calls  12>        4 ms  ComputeLinkImportLibraryOutputsForClean    1 calls  12>        5 ms  RegisterOutput                             1 calls  12>        5 ms  AssignTargetPaths                          1 calls  12>        8 ms  SetCABuildNativeEnvironmentVariables       1 calls  12>       10 ms  ComputeCLOutputs                           1 calls  12>       16 ms  PrepareForBuild                            1 calls  12>       53 ms  WarnCompileDuplicatedFilename              1 calls  12>      154 ms  PostBuildEvent                             1 calls  12>      295 ms  CoreCppClean                               1 calls  12>      301 ms  Manifest                                   1 calls  12>      302 ms  _Manifest                                  1 calls  12>      565 ms  ResourceCompile                            1 calls  12>      651 ms  _MASM                                      2 calls  12>     4252 ms  Link                                       1 calls  12>    320559 ms  ClCompile                                  1 calls  

Output is per-project.

Read More »

Comment on GotW #7c: Minimizing Compile-Time Dependencies, Part 3 by Roman M.

@Loïc Joly: I am aware of the tool you’ve mentioned. Our codebase is Visual Studio C++ – only. Some time ago I tried it and couldn’t get it running because of Microsoft’s implementation of STL. Current “README.txt” of “Include What You Use”-Project states:

“IWYU, like Clang, does not yet handle some of the non-standard constructs in Microsoft’s STL headers.”

On the other hand, I found recent message: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-October/032629.html in CLANG mailing list that states that support for MS-STL has improved, so maybe now it the time to give it another try. I just wish I had something similar from Microsoft.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Herb Sutter

@all: Yup, thanks for the cut-and-paste visual; I’m not sure how the old code resurfaced, but now it’s fixed. Acknowledgements to the first three who reported specific aspects: juanchopanza, anicolaescu, Bert Rodiers. Thanks, corrected.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Yuriy

Oops, looks like you forgot to remove the inheritance from the corrected code :)

class X : public A, <>

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by sergegers

You forgot to remove class B from inheritance list on the last code example.

Read More »

Comment on GotW #91 Solution: Smart Pointer Parameters by Bartosz Milewski

If I saw (d) or (f) in a code review I would most likely send it back to the author for a rewrite with this note:

If these are just out parameters, return them:

unique_ptr<widget> f();  (d)  shared_ptr<widget> f();  (f)

If you need to return more than the widget, repack the other return values as out parameters.

If the widgets are in/out, you’re really passing one widget as an in parameter and returning another, so separate them:

unique_ptr<widget> f(widget const * src_widget);  (d)  shared_ptr<widget> f(widget const * src_widget);  (f)

Using in/out parameters is already confusing enough; combining in and out ownership policies into one parameter is inviting a disaster.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Tom Swirly

Surely there’s a typo here? You’re still writing

class X : public A, private B {

but now B is nowhere defined, and is supposedly hidden entirely in the pimpl. Shouldn’t you be deleting

, private B

?

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Guru of the week 7 | C++, Qt, OpenGL, CUDA

[…] En complément, la question du GotW 95 : GotW #95: Thread Safety and Synchronization […]

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Guru of the week 7 | C++, Qt, OpenGL, CUDA

[…] GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 […]

Read More »

Comment on GotW #7b Solution: Minimizing Compile-Time Dependencies, Part 2 by Guru of the week 7 | C++, Qt, OpenGL, CUDA

[…] GotW #7b Solution: Minimizing Compile-Time Dependencies, Part 2 […]

Read More »

Comment on GotW #7a Solution: Minimizing Compile-Time Dependencies, Part 1 by Guru of the week 7 | C++, Qt, OpenGL, CUDA

[…] GotW #7a Solution: Minimizing Compile-Time Dependencies, Part 1 […]

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Mike

You forgot to excise “, private B” from the final version… and forward declare “class B”.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Bert Rodiers

The last code example has some errors. First of all, in the code X still (privately) inherits from B. Since it is now part of the impl, you don’t need to inherit anymore. Furthermore f returns B by value and g takes B by value, which means that you can’t remove the include for B. And lastly either you have to change unique_ptr to std::unique_ptr or “add using namespace std”.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Foo

Typo in the final solution as X still inherits from B. There also needs to be a forward declaration of B as it is both a return value and parameter for X’s functions.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by avjewe

Your new improved x.h still says “, private B” and fails to say “class B;”

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Alexandre Chassany

Hi,

I maybe mistaken but in the final version of the header there is still a private inheritance from B. Wasn’t it the whole point to remove it ? :)

Furthermore, i’m kinda confused. I agree that using composition you can get rid of the

#include "b.h"

, but B is still reference in the public part of the class X:

  B  f( int, char* );  C& g( B );  

Will it still work if we remove the

#include "b.h"

?

Thx

Alex

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by John Ralls

Umm, looks like you forgot to actually remove the inheritance from B. Also needs to have a forward decl for B for the second and fourth member functions.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by John Ralls

Umm, don’t you want to remove the ‘private B’ from the class X declaration line and add a ‘class B;’ declaration so the compiler won’t complain about the second member function declaration?

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by anicolaescu

You missed removing “private B” from X’s super-classes.
Also, shouldn’t B be forward-declared? There are methods in X which make use of it.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Steve Gilham

At time of writing, the “after” still has the inheritance
[CODE]class X : public A, private B {[/CODE]
and not the composition-only
[CODE]class X : public A {[/CODE]

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Robert

Little typo: In your final code, X still privately inherits from B.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by juanchopanza

Clearly I am having formatting issues. Anyway, I meant class X still inherits privately from class B.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by KrzaQ

I think you forgot to remove B from the list of X’s base classes, unless I’m badly misunderstanding something.

Read More »

Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by juanchopanza

Typo: in your final code sample, still inherits privately from .

Read More »
 
Delievered to you by Feedamail.
Unsubscribe