Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yes, I've had equally confusing compile errors from C++ due to its lookup rules. For example removing an unused parameter from a function can cause that function not to be found anymore! I'd argue that is more confusing than this Rust issue.


What does this comment mean? Function parameters used or not are part of the function signature, so obviously would participate in any form of argument dependent lookup.


I mean, you can do as small a change as adding a const somewhere, and cause an (almost) independent file somewhere else in your codebase to hit the wrong overload.


Perhaps a case where after removing the unused parameter and updating all the call sites, none of the calls resolve to the original function anymore.


And we would expect this behavior why?


If you start with

    void foo(std::string x, int y);
    void foo(const char* x);
Then calls to foo("bar", 0) would resolve to the first overload: the second isn't a match at all, but the first is a match with an implicit conversion from const char* to std::string. But if you removed the second parameter, including arguments at all call sites, then foo("bar") would match the second better because it doesn't involve any conversions, so it would be selected instead of the first.


There was an argument that was not used by the function implementation. I removed it from the signature entirely - at the definition and the call sites.

Boom. No longer compiles.

Yes I understand the complex and surprising rules that cause this to happen. That doesn't make them any less complex and surprising.


"not used by the function implementation" doesn't mean "not passed in by callers".

The callers won't find a matching signature once there is 1 less parameter. I don't see what is confusing about it.

You probably misunderstood that warning as "No callers pass this parameter", which btw would only make sense for a parameter with a default value.


I removed the parameter from the definition and call sites.

I went from

    void foo(A a, B b) {
       // Only use a
    }
    ...
    foo(x, y);
To this

    void foo(A a) {
       // Only use a
    }
    ...
    foo(x);
And it stopped compiling. There were no other functions called `foo` so it is nothing to do with overloading.

I'll give you the answer if you want or we can leave it a mystery so you can experience how confusing that behaviour is...


Sigh. This is entirely expected behavior, and in fact, is _necessary_ behavior. If changing signatures in that way continued to allow code to "compile" with reckless abandon, so many things would break. I think before complaining, you need to understand how general symbol resolution, name mangling, and argument dependent lookup work. And if you're too impatient to learn, you're not actually in a position to criticize.


All I can think of is Koenig lookup [1]: B and foo were defined in a namespace, and the calls to foo were not in that namespace and didn't explicitly qualify foo but still found it.

[1] https://en.m.wikipedia.org/wiki/Argument-dependent_name_look...


Yes I’d like to know the answer.


Perhaps the argument had a default value so call sites didn't need to mention it. Although I can't think of removing an argument with a default value would change its priority in the overload set. But I definitely don't know all the rules so I can believe that it could!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: