| ||||
| 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 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 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 Comment on GotW #7c: Minimizing Compile-Time Dependencies, Part 3 by Klimax
@Roman M: 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. Comment on GotW #7c Solution: Minimizing Compile-Time Dependencies, Part 3 by Steve Gilham
At time of writing, the “after” still has the inheritance 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 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 » | ||||
| | ||||
| ||||
Monday, January 6, 2014
FeedaMail: Comments for Sutterâs Mill
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment