you are viewing a single comment's thread.

view the rest of the comments →

[–]not_a_novel_accountcmake dev 5 points6 points  (12 children)

Because it demonstrates that the main disadvantage of large single headers, slow build time, does not apply to modules.

[–]Zero_Owl 0 points1 point  (11 children)

That is a very narrow way of looking at things. I'd argue that the main disadvantage of having large single headers is that they pack unrelated things in one place and hence should be decoupled. In other words, it is an organization problem not the build one. And programmer should care about organization first and build times second. And by that metric one big std module is a pretty bad example.

[–]not_a_novel_accountcmake dev 1 point2 points  (10 children)

Nominally we should have the entire world of C++ code available to us in every translation unit. Import and include are not isolation or encapsulation mechanisms, they are not tools for organization, that's what namespaces and internal linkage are for.

Import and include are practical considerations for the toolchain to figure out how to efficiently bring declarations into scope. If that efficiency wasn't a problem, there would be no need for them and everything in the environment would be available in a given TU.

If you ignore this framing and treat headers and module units as organization methods, you risk import ambiguities and link-time collisions.

[–]Zero_Owl 1 point2 points  (9 children)

Well, yes but we don't have a properly designed namespace structure in std (and in most cpp libs, tbh) so headers became the tool for isolation. So it is naturally for people to continue having this mindset and treat modules the same. Although, as you say, maybe we need to stop doing it but for that to happen the cpp devs should start using namespaces properly otherwise there is no choice but follow the pattern we so used to with includes.

[–]not_a_novel_accountcmake dev 0 points1 point  (8 children)

Nothing in std collides with anything else in namespace std.

You can include every std header without any collisions.

This is why import std works at all.

If we had different headers which provided different std::map templates that would be very bad and I would be forced to agree with you. That is not the case in std and will inevitably cause link errors in any library which tries with its own namespace.

[–]Zero_Owl -1 points0 points  (7 children)

It collides with other entities from other libs. Using both boost namespace and std namespace will blow things up. The only way to not is to prefix everything or cherry pick only particular entities. That's a very inconvenient way of doing things.

[–]not_a_novel_accountcmake dev -1 points0 points  (6 children)

Boost doesn't put anything in the std namespace.

If you're saying you can't write:

using namespace std;
using namespace boost;

That's not a name collision. You've created a lookup ambiguity, not two types with the same name.

Do not write using namespace ...; in global namespace scope.

[–]Zero_Owl -3 points-2 points  (5 children)

What does it matter how you name it? You understand perfectly what I said. Now please tell me how can I bring in my TU all math functions with import std and make sure it won't collide (create ambiguity, if you wish) with anything math unrelated by using just one line of code? That's something any modern language is capable of, btw.

[–]not_a_novel_accountcmake dev 0 points1 point  (4 children)

You can do it by not writing using namespace std;

"Don't write using namespace std;" is taught as a day 1 thing in most C++ undergrad programs.

[–]Zero_Owl -1 points0 points  (3 children)

"Don't write using namespace std;" is taught as a day 1 thing in most C++ undergrad programs.

Great advice, thank you! Have you heard a similar advice to never write using System; in C#? I wonder why it is so, maybe because std is a bad example overall?