Variable name same as function name giving compiler error... Why?
Asked Answered
A

2

6

Ran into an interesting issue today and am trying to understand why.

Consider the following:

class Base
{
public:
    Base(){}
    ~Base(){}
    static void function1(){}
        void function2()
        {
           int function1;
           function1 = 0;
           function1();   //<-compiler error
           function1 = 1;
        }
};

I am getting the following error:

expression preceding parentheses of apparent call must have (pointer-to-) function type

I think I understand why I am getting this error:

  1. When function1 is called by itself outside of function2(), it is actually a function pointer to function1().

  2. Inside the scope of function2, when int function1 is declared, 'function1 the variable' shadows 'function1 the function pointer'.

  3. When function1() is called inside function2(), it is assuming function1 is the variable and is giving an error.

  4. This is fixed by calling Base::function1(); inside function2().

My question is this: Why doesn't the compiler give an error when declaring int function1;? Shouldn't this not be allowed?

Aenea answered 19/1, 2016 at 21:17 Comment(5)
You're almost correct, except that there are no function pointers involved, only functions. Name shadowing is allowed, which is why it's not an error.Diakinesis
-Wshadow, or whatever your compiler calls it.Mb
You can always declare any name in a new scope, it will hide the same name if that name already existed in an outer scopeVaca
Why do you think function1 must be a pointer? function1 is an identifier, and if you use it inside function2 it resolves to a variable of type int, and you can't call a variable of type int.Nacred
The compiler has the needed information to make this code sample compile correctly. If the variable function1 was a functor or a lambda though, that would be ambiguous. And it would get very confusing and have a fair number of ambiguous usage cases depending on how you use function1, so it's easier/nicer to have simpler name lookup rules which prohibit this instead of trying to figure out your intention.Hedgehop
P
13

The local variable overwrites the designator for the method in the local block. Try this->function1() to call it nevertheless.

Or better yet, rename the one or the other to help people reading your code avoiding confusion (and this includes your future yourself).

Pastor answered 19/1, 2016 at 21:19 Comment(2)
Thanks for your answer! Feel free to edit your comment into your answerGrub
Thanks. It just seemed unintuitive that the error occurred where it did.Aenea
E
3

To answer your question: "Should this be allowed":

In c++ you can have different entities with the same name if they exist in different scopes (like in your example). This is very useful feature in general, because it allows you to use whatever names you like for your entities assuming that you provide them in scope e.g. in namespace. Said that, compiler needs some algorithm to select entity when it sees name in code. In c++ standard process of matching name to declaration is called 'name lookup'. You can see description of this algorithm e.g. here cppreference or directly in standard draft.

Erymanthus answered 19/1, 2016 at 21:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.