Sometimes I like C++ just fine

Oct 10, 2019 at 9:26pm
And sometimes I want it to burn to a very nice crisp. That and everything it ever touched.

Just hit this ADL problem:
https://quuxplusone.github.io/blog/2018/06/17/std-size/

yay.


’Cause, you know, given the choice between two (or more) ADL matches, the compiler doesn’t think to choose from the explicitly active namespace...
Oct 10, 2019 at 9:36pm
In 20 years, I run into this problem exactly one time.
Oct 10, 2019 at 11:13pm
What’s your point?

The idea itself is only about 15 years old, and C++ didn't have it before 2011.

For your reference, I’ve been hacking for about 30 years, not quite half of that in C++.


ADL is a nice idea... until the Standard Library decides to use up all the common identifiers...


[edit]
It occurs to me that I am probably reading you wrong.

You’re probably saying, "Yeah, that’s an odd problem that likes to bite when you aren’t looking...”, and I’m all, “FLAME ON!”

Sorry. Flame off.

Last edited on Oct 10, 2019 at 11:16pm
Oct 10, 2019 at 11:17pm
My point is, that I have only one problem with ADL since I programm in C/C++. So it can not be such a big problem ;)
Oct 11, 2019 at 1:01am
I started reading the article you linked, and was like "wait how is this ADL, it's just because you injected size into the global namespace", but then I understood once I go this paragraph:
So the author tried replacing using namespace std; with a list of explicit using-directives. Unfortunately, this doesn’t help. We’re getting something we don’t expect out of namespace std, but it’s not because we using the namespace. It’s because of argument-dependent lookup (ADL). We made an unqualified call to size, where one of the arguments was a std::vector. This unqualified call, by ADL, naturally finds any function named size in any associated namespace of the argument type std::vector (and, incidentally, also considers namespace hr, although this has been widely regarded as a bad move.)

Yeah I can see that being really annoying for people that had the foresight to make those things templates before the standard did. Part of me is glad that the committee was able to make overall-positive, but breaking changes like that, but I can understand the pain.

I was watching a recent video where the presenter was talking about multi-step refactoring of very large codebases, and Argument-Dependent Lookup was one of the challenges.
https://www.youtube.com/watch?v=v_yzLe-wnfk
Last edited on Oct 11, 2019 at 1:02am
Oct 11, 2019 at 3:42am
The whole point of namespaces is to control visibility of names, and when ADL decides that your very explicit namespace controls mean nothing, then, well, FLAME ON. LOL

ADL is great, but not recognizing that an object in a foreign namespace should not have the same precedence as an object in your explicit, current namespace — that is a design flaw.

IMO, the compiler should not be generating code that makes your code invalid.
Oct 11, 2019 at 1:07pm
I'm not sure what the original rationale for ADL was. Was was the problem it was trying to solve? It sure does seem like an anti-feature.

Would tricks like "using std::swap;" work without ADL? I would imagine so; the compiler should still be able to match the different overloads.
Last edited on Oct 11, 2019 at 1:10pm
Oct 11, 2019 at 2:49pm
Ah, the fun of a committee mandating a continually evolving standard, implemented by committees.

whee :|

Old code shouldn't break, but it does rot.
Oct 11, 2019 at 2:51pm
I'm not sure what the original rationale for ADL was. Was was the problem it was trying to solve? It sure does seem like an anti-feature.

The hello world program relies on ADL. That is, it makes overloaded operators usable, and allows for library extension.

Would tricks like "using std::swap;" work without ADL?

The point of
using std::swap; swap(a, b);
is that it prefers to call the client's swap overload if it exists. Otherwise, it falls-back to the less-efficient and more general algorithm in the standard library.

That phrase only appears in generic code, so ADL is required in order to search the client's (maybe third-party) namespace for a suitable swap().

See Herb Sutter's A Modest Proposal: Fixing ADL:
https://wg21.link/p0934
Last edited on Oct 11, 2019 at 2:56pm
Oct 11, 2019 at 3:17pm
Thanks, your link explains it perfectly.
Absent ADL, the choices to fix Example 1 would be: a) to qualify the << call (e.g., std::operator<<(std::cout, “Hello, world” );)
Oct 11, 2019 at 3:30pm
The main reason ADL doesn’t bite us harder most of the time is that there are:
  • specific use patterns — for example, overloading << for stream insertion
  • specific types used in an ADL namespace do not conflict with types in any other namespace
    — for example, std::setw()

The swap() example is both an example and a counter-example.

As an example, you can overload swap() to work specially over your specific (namespace qualified) types of objects.

As a counter-example, writing your own generic swap function will cause the compiler to flip out because it can’t decide which swap to use with a given generic argument. This is a common problem for C++ newbies in general, especially those trying to play with sort algorithms and the like, who are unfamiliar with the language and its weirdness.
https://www.google.com/search?q=c%2B%2B+swap+ambiguous
Oct 11, 2019 at 3:41pm
I am a self-taught (poorly) hobbyist programmer still finding my way through the C++ minefield.

This ADL issue is, IMO, made worse by the idiotic insistence instructors have with using namespace std; inserted in code taught to noobs.

Namespaces were added to the language standard for a reason. Fully qualify every use of the standard library. I do and it has become 2nd nature. My fingers go on auto-pilot.

Saving a few keystrokes makes my code "smell" bad to me now.

Oct 11, 2019 at 5:18pm
the huge irony of that was that namespace std was considered to be the right way for a while. Its taught because schools lag behind industry/professionals, in part, so they are still operating from back when this was 'good practice'.

Professors are often people that worked for a while (if you are lucky. Many never have done anything real), got their PHD, decided to teach and do research, and then stopped learning things like language trends and went off to focus on highbrow R&D problems. So they often teach their intro and intro+1 classes relying on what they knew when they retired from coding with few updates to that knowledge.
Last edited on Oct 11, 2019 at 5:21pm
Oct 12, 2019 at 10:26pm
I don’t know of any time that “using namespace anything” was considered correct. It was introduced for the express purpose of untangling identifier pollution.

So... anyone teaching it as correct was, as you said, out of touch.
Oct 13, 2019 at 1:18am
So... anyone teaching it as correct was, as you said, out of touch.

My first professor said it was bad practice and then proceeded to always use it and teach the whole class to use it.

My current professor didn't say it was bad practice and encourages it's use. He does this thing where he smirks when he thinks he's being clever and it just pisses me off. It really shouldn't, but it just does. Anyway, he encouraged it's use saying you write less code by omitting "std::", didn't feel like fighting him over every thing he says that is wrong or not recommended.
Oct 13, 2019 at 1:35am
I'm not sure how true this is, but I remember reading somewhere that the initial reason for people using using namespace std was to transition from pre-standard C++ (including e.g. #include <iostream.h>, where there were no namespaces) to standard C++ without much code change.
Oct 13, 2019 at 3:25am
Yes, that's one part of the feature rationale given in D&E (pg. 408).
BjarneStroustrup wrote:
Personally, I consider using-directives primarily as a transition tool.
Last edited on Oct 13, 2019 at 3:27am
Oct 13, 2019 at 4:32pm
A transition tool that is no longer needed, if only C++ was taught to modern standards. Too many instructors don't.

Older code is one thing. Writing new code to old, near-obsolete standards is not good.

@TwilightSpectre, I read something similar years ago myself. That is the main reason why I don't use it.

I really don't like in general using-declarations either, for example: using std::cout;

If I do have a using-declaration I restrict the scope as narrowly as possible. The way Boost is laid out makes me bend the "won't use ever" rule.

using also has a place as a type alias, if used sparingly. Rules can be bent when readability is enhanced.

zapshe wrote:
My first professor said it was bad practice and then proceeded to always use it and teach the whole class to use it.

Saint Bjarne says much the same, bad practice, and still uses it in his lectures and books on C++.

It wouldn't be so egregiously horrible, but he buries the using-directive in a header file he reuses again and again.

Too bad a perfectly good keyword (auto) is ignored by many instructors. C++11 usage makes replacement typing loooooong Standard Library/STL constructs easier to understand and read.

STL containers' iterators for example.
Oct 16, 2019 at 3:43pm
I never saw much reason for the namespace std, just the sites like this one were all recommending (or quietly using) it, books were using it, most code found online was using it, etc. No one said not-to and I don't even recall anyone saying bad practice. Came back from not using the language for a couple years and it was suddenly a big deal to everyone.

auto annoys me. I want to know what things are. I get the reasons, but they don't sit with me. Its a couple of small steps away from those awful typeless languages where one min a variable is a string, next its a double, then a boolean... etc. And it kills self documenting code when the user has to actually figure out what the compiler did there if there is a bug. I can't think of any good reason to use it, not sure what it does that you can't do by being explicit which I find much more readable. Ive gotten better at dealing with it, but I still don't like it and won't USE it myself.
Last edited on Oct 16, 2019 at 3:45pm
Oct 16, 2019 at 4:26pm
I certainly prefer to use auto very judiciously. I'll use it in places where the actual type is obvious from context, and is long-winded to write out explicitly. For example, when declaring iterators:

1
2
3
4
5
std::vector<namespace1::namespace2::MyLongClassName> myVector;

// ...

auto myIter = myVector.begin();


it's obvious what type myIter should be, and the code is more readable than:

std::vector<namespace1::namespace2::MyLongClassName>::iterator myIter = myVector.begin();

Like you, I wouldn't advocate using it in places where it obscures information that's not obvious.
Last edited on Oct 16, 2019 at 4:27pm
Topic archived. No new replies allowed.