Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler find my function if is not yet declared?

Contrary to my expectations, this program works:

#include <iostream>


namespace a { struct item{}; }
namespace b { struct item{}; }


template<typename T>
void func(T t) { do_func(t); }


int main()
{    
    func(a::item{});
    func(b::item{});
}


namespace a { void do_func(item) { std::cout << "a::func\n"; } }
namespace b { void do_func(item) { std::cout << "b::func\n"; } }

Output:

a::func
b::func

Verifications with online compilers:

  • gcc 4.8
  • clang 3.4

If the instantation of func<T> occurs in the body of main then I would expect that a::do_func and b::do_func are not yet declared.

How can this work?

Update

According to @Marc Claesen the reason that above works is:

template instantiation is performed after reading all of the source

However, then why does this code does not work:

#include <iostream>

template<typename T>
void func(T t) { do_func(t); }

int main()
{
    func(1);
}

void do_func(int) { std::cout << "do_func(int)\n"; }

See gcc-4.8:

error: 'do_func' was not declared in this scope,
and no declarations were found by argument-dependent
lookup at the point of instantiation [-fpermissive]

clang++ 3.4:

error: call to function 'do_func' that is neither
visible in the template definition nor found by
argument-dependent lookup

So it seems that the combination of function template and ADL are required to make it work.

However, I don't understand why this is so..

like image 361
StackedCrooked Avatar asked May 18 '13 10:05

StackedCrooked


People also ask

Can you call a function without declaring it?

You can't call a function without declaring it first. It's how it works in C++..

Is it necessary to declare function before use?

It is always recommended to declare a function before its use so that we don't see any surprises when the program is run (See this for more details).

Is it compulsory to declare function before its calling in C?

Actually, it is not required that a function be declared before use in C. If it encounters an attempt to call a function, the compiler will assume a variable argument list and that the function returns int.

Can we define function without declaration in C?

Function declaration is required when you define a function in one source file and you call that function in another file. In such case, you should declare the function at the top of the file calling the function.


1 Answers

It works because of two interesting things:

  • two-phase name lookup which is performed to lookup dependent names.
  • and Argument Dependent Lookup (ADL).

Have a look at this:

  • The Dreaded Two-Phase Name Lookup

In short, do_func is a dependent name, so in the first phase (when the file is only parsed but the function template is not instantiated) the compiler does not resolve the name do_func, it only checks the syntax and it sees it is a valid function call. That is all. In the second phase when the function template is instantiated (and thus T is known), the name do_func is resolved and at this time it also uses ADL to lookup the name.

Note that ADL works only for user-defined types. It doesn't work for built-in types, which is why your second code (i.e func(1)) doesn't work!

like image 85
Nawaz Avatar answered Oct 24 '22 02:10

Nawaz