can compiler tell me which overloaded or template function it chose? - c++

Specifically using g++ on linux, is there a way to determine which overloaded or template function was chosen for a particular statement?
More specifically, I don't assume that I necessarily know all the possible choices, which may be in header files coming from various libraries. And even if I did, I don't assume that I could modify the relevant code.

I don't know of a way to do this directly.
The simplest solution is to set a breakpoint at the call site and single-step into whatever function is called; your debugger can then tell you which function you're in.
An IDE like Eclipse CDT can do overload and template resolution itself (if everything works right), so right-clicking on a function call and going to the function declaration will take you to the appropriate function.
By deliberately creating an ambiguous function call, as described in this answer, you can get a list of all available overloads and templates and can probably figure out which one is being invoked from there.
As Matthieu M. said, Clang can dump its AST. This requires some interpretation, but it can help you figure out which function is being called.

Partial answer.
You can use non standard macro for printing name of function in run-time (Macro / keyword which can be used to print out method name?
For GNU C++:
#include <iostream>
using namespace std;
template <typename T>
void f(const T & t)
{
cout << __PRETTY_FUNCTION__ << endl;
}
void f(const string &)
{
cout << __PRETTY_FUNCTION__ << endl;
}
void f(int)
{
cout << __PRETTY_FUNCTION__ << endl;
}
int main()
{
f(1.0);
f(1);
f(string("sss"));
string a;
f(a);
}
Output from this code (http://ideone.com/PI39qK):
void f(int)
void f(int)
void f(const std::string&)
void f(T&) [with T = std::string]

Related

Why does this template function not behave as expected?

I was reading about template functions and got confused by this problem:
#include <iostream>
void f(int) {
std::cout << "f(int)\n";
}
template<typename T>
void g(T val) {
std::cout << typeid(val).name() << " ";
f(val);
}
void f(double) {
std::cout << "f(double)\n";
}
template void g<double>(double);
int main() {
f(1.0); // f(double)
f(1); // f(int)
g(1.0); // d f(int), this is surprising
g(1); // i f(int)
}
The results are the same if I don't write template void g<double>(double);.
I think g<double> should be instantiated after f(double), and therefore the call to f in g should call f(double). Surprisingly, it still calls f(int) in g<double>. Can anyone help me understand this?
After reading the answers, I figured out what my confusion really is.
Here is an updated example. It is mostly unchanged except that I added a specialization for g<double>:
#include <iostream>
void f(int){cout << "f(int)" << endl;}
template<typename T>
void g(T val)
{
cout << typeid(val).name() << " ";
f(val);
}
void f(double){cout << "f(double)" << endl;}
//Now use user specialization to replace
//template void g<double>(double);
template<>
void g<double>(double val)
{
cout << typeid(val).name() << " ";
f(val);
}
int main() {
f(1.0); // f(double)
f(1); // f(int)
g(1.0); // now d f(double)
g(1); // i f(int)
}
With the user specialization, g(1.0) behaves as I expected.
Should the compiler not automatically do this same instantiation for g<double> in the same place (or even after main(), as described in section 26.3.3 of The C++ Programming Language, 4th edition)?
The name f is a dependent name (it depends on T via the argument val) and it will be resolved into two steps:
Non-ADL lookup examines function declarations ... that are visible from the template definition context.
ADL examines function declarations ... that are visible from either the template definition context or the template instantiation context.
void f(double) is not visible from the template definition context, and ADL will not find it either, because
For arguments of fundamental type, the associated set of namespaces and classes is empty
We can slightly modify your example:
struct Int {};
struct Double : Int {};
void f(Int) {
std::cout << "f(Int)";
}
template<typename T>
void g(T val) {
std::cout << typeid(val).name() << ' ';
f(val);
// (f)(val);
}
void f(Double) {
std::cout << "f(Double)";
}
int main() {
g(Double{});
}
Now ADL will find void f(Double) in the second step, and the output will be 6Double f(Double). We can disable ADL by writing (f)(val) (or ::f(val)) instead of f(val). Then the output will be 6Double f(Int), in agreement with your example.
The problem is f(double) has not been declared at the point where you call it; if you move its declaration in front of the template g, it will get called.
Edit: Why would one use manual instantiation?
(I'll talk about function templates only, analogous argumentation holds for class templates too.) The main use is to reduce compilation times and/or to hide the code of the template from users.
C++ program are built into binaries in 2 steps: compilation and linking. For the compilation of a function call to succeed only the header of the function is needed. For the linking to succeed, an object file containing compiled body of the function is needed.
Now when the compiler sees a call of a templated function, what it does depends on whether it knows the body of the template or only the header. If it only sees the header it does the same thing as if the function was not templated: puts information about the call for the linker to the object file. But if it also sees the body of the template it does also another thing: it instantiates proper instance of the body, compiles this body and puts it into the object file as well.
If several source files call the same instance of the templated function, each of their object files will contain a compiled version of the instance of the function. (Linker knows about this and resolves all the calls to a single compiled function, so there will only be one in the final binary of the program/library.) However in order to compile each of the source files the function had to be instantiated and compiled, which took time.
It's enough for the linker to do it's job if the body of the function is in one object file. To manually instantiate the template in a source file is a way to make the compiler put the body of the function into the object file of the source file in question. (It's kinda as if the function were called, but the instantiation is written in a place where function call would be invalid.) When this is done, all the files that call your function can be compiled knowing only the header of the function, thus saving time it would take to instantiate and compile the body of the function with each of the calls.
The second reason (implementation hiding) might make sense now. If a library author wants users of her template function to be able to use the function, she usually gives them the code of the template, so they can compile it themselves. If she wanted to keep the source code of the template secret she could manually instantiate the template in the code she uses to build the library and give the users the object version thus obtained instead of the source.
Does this make any sense?

How to call a function whose prototype is scoped inside another function?

to declare a function prototype we declare it outside and on the top which means right before the function definition.
1- I wonder why c++ allows declaring prototypes scoped inside the body of other functions' definitions?
2- How to call a function whose prototype being inside another function's body?
here is an example:
#include "stdafx.h"
#include <iostream>
using namespace std;
void Bar()
{
cout << "Bar..." << endl;
void Baz();
}
int main()
{
void Foo();
Foo();
Bar();
Baz(); // how to call this function?
cin.get();
return 0;
}
void Foo()
{
cout << "Foo..." << endl;
}
void Baz()
{
cout << "Baz..." << endl;
}
A function prototype inside one function isn't visible inside another, so the code you've written here won't work. However, there's nothing stopping you from providing another function prototype inside of main:
int main()
{
void Foo();
Foo();
Bar();
void Baz();
Baz();
cin.get();
return 0;
}
That having been said, it's pretty unusual to write code like this - if you mean to prototype the function, just do so at global scope. It's rare to see function prototypes defined inside of individual functions and is almost always a mistake or extremely poor coding style.
C++ allows this for two reasons:
Backwards compatibility. This is legal C code, and historically C++ tried to maintain compatibility with C whenever possible. (There's a lot of legal C code that won't compile in C++, so this isn't a hard-and-fast rule, but it's a good guiding philosophy.)
The "Why Not?" principle. Function prototypes are really just declarations of functions. C++ lets you declare all sorts of objects at different points in time. Allowing function declarations like this inside of a function follows as a special case of allowing for declarations, so explicitly disallowing it would require extra verbage in the spec and potentially might hurt someone in a really bizarre case down the line.
Arguably, this was a bad decision, because it leads to C++'s Most Vexing Parse. The following line of code, for example, is interpreted as a function prototype:
std::vector<int> x(); // Oops - it's a function prototype!
Even worse is something like this:
std::istream input;
std::vector<int> x(istream_iterator<int>(input), istream_iterator<int>()); // Oops - it's a function prototype!
This was addressed by adding in the new brace initialization syntax:
std::vector<int> x{}; // Okay, a vector.
std::vector<int> x{istream_iterator<int>{input}, istream_iterator<int>{}}; // Sure, that's fine too.

gcc template resolution and namespaces

Warning, C++ hating ahead...
I have seen here slightly different variations of this issue, here is my take
namespace space {
}
template <typename T> struct C
{
void foo() {
using namespace space;
bar(t);
}
T t;
};
class A {
};
namespace space {
void bar(const A& a){
}
}
int main()
{
C<A> c;
c.foo();
return 0;
}
if bar is not inside a namespace, everything compiles ok. Putting a namespace breaks compilation with gcc. What is more interesting - gcc finds the function, but just don't feel like using it:
ConsoleApplication1.cpp: In instantiation of 'void C<T>::foo() [with T = A]':
ConsoleApplication1.cpp:26:10: required from here
ConsoleApplication1.cpp:8:8: error: 'bar' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point
instantiation [-fpermissive]
bar(t);
^
ConsoleApplication1.cpp:18:6: note: 'void space::bar(const A&)' declared here, later in the translation unit
void bar(const A& a){
Is there any sane reason for this behaviour, except that the standard says so? And is there any switch I can make gcc accept this code, since it seems there is no technical issue, and I do not see why such code should not work from a pure language standpoint.
templates are not macros. Name lookup of symbols is done in two contexts: first, where you wrote the template, and second pass of only argument-dependent lookup (ADL, or Koeing Lookup) when you pass the template a type (when the template "factory" is instantiated into an actual class or function).
When the function is in the same namespace as A, it is found via ADL. When it is not, it will not be. So when you moved the bar function into space::bar, it was no longer ADL-found with an argument of type A.
This is intentional, to both prevent your template from meaning completely different things at different spots, and to allow non-member interface extensions to types in their own namespace only.
Either use a traits class, stick such helper functions in the same namespace as the type, or pass in functors.
A traits class is probably easiest. Create a class with a static function foo (if you want a default implementation: otherwise leave empty). Call it from your template. Specialize it for A. Now you can implement special behavior for your A type at that point -- it could even call your space::bar function if that function is in view.
Putting bar in the same namespace as A is another solution, and I find it scales better than traits classes. Many of my personal traits classes end up falling back on an ADL lookup, as that lets me inject the handling code right next to where I define A. (The use of traits classes lets me also have my trait handle things in std, where I am not allowed to inject functions for ADL purposes for types living in std (you can inject ADL functions into std, but only for your own types))
The functor solution is how std::map works -- while it falls back on std::less<T> which falls back on operator<, it takes a functor that lets you specify how the key type should be compared within this map.
Is there any sane reason for this behaviour, except that the standard says so?
Sane or not, C++ usually requires names to be declared before use. You don't declare bar before using it; specifically, using namespace space only imports names that have been declared at that point, and not bar.
(If you care about the reason, it's because C++ inherited its declaration rules from the languages of half a century ago, when computers were somewhat primitive. Rules like this allowed compilation in a single pass, so that the compiler didn't have to keep waiting for the operator to put the stack of punch cards back into the hopper. Or something like that; I'm not quite sure how computers worked back then.)
And is there any switch I can make gcc accept this code
As the error message says, -fpermissive. But your code won't be portable if you don't stick to the standard.
This error has nothing to do with namespaces or templates at all, but is the standard error of using a function before it has been declared. Just as you cannot do:
void caller() { callee(); }
void callee() {}
But must instead do:
void callee() {}
void caller() { callee(); }
Or:
void callee();
void caller() { callee(); }
void callee() {}
... the same applies for more complicated functions involving templates and namespaces. Note that if you reorder slightly, it works just fine:
class A {
};
namespace space {
void bar(const A& a){
}
}
template <typename T> struct C
{
void foo() {
using namespace space;
bar(t);
}
T t;
};
int main()
{
C<A> c;
c.foo();
return 0;
}

Why do g++ and clang break the namespace abstraction in this case?

This compiles:
struct str {};
namespace a
{
void foo(str s) {}
}
namespace b
{
void foo(str s) {}
void bar(str s) { foo(s); }
}
int main(int, char**)
{
return 0;
}
but this doesn't (with the struct definition moved inside namespace a)
namespace a
{
struct str {};
void foo(str s) {}
}
namespace b
{
void foo(a::str s) {}
void bar(a::str s) { foo(s); }
}
int main(int, char**)
{
return 0;
}
The error I get is
bad.cpp: In function ‘void b::bar(a::str)’:
bad.cpp:12: error: call of overloaded ‘foo(a::str&)’ is ambiguous
bad.cpp:10: note: candidates are: void b::foo(a::str)
bad.cpp:5: note: void a::foo(a::str)
It seems reasonable to expect that, since a::foo is not in scope, the call to foo can only refer to b::foo.
Is there a good reason for compilation to fail (and if so, what is it), or is it a deficiency in the implementations (of both major compilers)?
This is because of the way name lookup, and in particular Argument-Dependent Lookup (ADL), works. When deciding which functions may be a candidate for resolving your call, the compiler will first look up names in:
The namespace where the function call occurs;
The namespace(s) where the type(s) of the argument(s) is/are defined.
If no function with that name is found in those namespaces, the compiler will proceed inspecting parent namespaces of the namespace where the call is made.
So what is going on in the examples from your question?
In the first case, str is defined in the global namespace, and there is no function called foo() there. However, there is one in the namespace where the call occurs (b): so the compiler has found a valid name, name lookup stops, and overload resolution starts.
But well, there's only one candidate function! So the task is easy here: the compiler invokes b::foo().
In the second case, on the other hand, str is defined in the a namespace, and when calling foo(s), the compiler will again look in the namespace where the call is made (b) and in the namespace where the type of the argument (str) is defined - this time, a.
So now there are two functions with matching names for resolving the call: enter overload resolution! Alas, both functions are equally good (exact matches, no conversion required). Hence, the call is ambiguous.

Nested functions are not allowed but why nested function prototypes are allowed? [C++]

I was reading the linked question which leads me to ask this question.
Consider the following code
int main()
{
string SomeString();
}
All says, compiler takes this as a function prototype and not as a string object. Now consider the following code.
int main()
{
string Some()
{
return "";
}
}
Compiler said this is invalid as I guess nested function definition is not allowed. If it is not allowed, why nested function prototypes are allowed? It is not giving any advantage rather than making confusion (or am I missing some valid points here?).
I figured out the following is valid.
int main()
{
string SomeFun();
SomeFun();
return 0;
}
string SomeFun()
{
std::cout << "WOW this is unexpected" << std::endl;
}
This is also confusing. I was expecting the function SomeFun() will have a scope only in main. But I was wrong. Why compiler is allowing to compile code like the above? Is there any real time situations where code like the above makes sense?
Any thoughts?
Your prototype is just 'Forward Declaration'. Please check out the Wikipedia article.
Basically, it tells the compiler "don't be alarmed if the label 'SomeFun' is used in this way". But your linker is what's responsible for finding the correct function body.
You can actually declare a bogus prototype, e.g. 'char SomeFun()' and use it all over your main. You will only get an error when your linker tries to find the body of your bogus function. But your compiler will be cool with it.
There are lots of benefits. You have to remember the function body is not always in the same source code file. It can be in a linked library.Also, that linked library may be have a specific 'link signature'.Use conditional defines you may even select the correct link signature at build time using your scoped prototypes.Although most people would use function pointers for that instead.
Hope this helps.
Just as a side note, C++03 does have a roundabout way of defining local functions. It requires abusing the local-class feature:
int main()
{
struct Local
{
static string Some()
{
return "";
}
};
std::cout << Local::Some() << std::endl;
}
This is a convention from C -- like many -- which C++ has adopted.
The ability to declare a function inside another function in C is a decision that most programmers probably consider regrettable and unnecessary. Particularly with modern OOP design where function definitions are comparatively smaller than they are in C.
If you would like to have functions that only exist in the scope of another function, two options are boost::lambda and C++1x lambda.
As to why your declaration of
void f() {
void g(); g();
}
is better than this one
void g();
void f() {
g();
}
It's generally good if you keep declarations as local as possible, so that as few name clashes as possible result. I say it's arguable whether declaring a function locally (this way) is really fortunate, as i think it's still better to ordinary include its header and then go the "usual" way, which is also less confusing to people not knowing about that. Sometimes, it's also useful to work around a shadowed function
void f() {
int g;
// oops, ::g is shadowed. But we can work around that
{
void g(); g();
}
}
Of course, in C++ we could call function g using its_namespace::g() - but in the old days of C, that wouldn't have been possible, and that thing allowed the programmer to still access the function. Also note that while syntactically it is not the same, semantically the following does also declare a function within a local scope, that actually targets a different scope.
int main() {
using std::exit;
exit();
}
As a side note, there are more situations like that where the target scope of a declaration is not the scope where that declaration appears in. In general, the entity you declare becomes a member of the scope in which the declaration appears. But that's not always the case. Consider for example friend declarations, where that thing happens
struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!
Even though the function declaration (and definition!) of f happened within the scope of X, the entity (the function itself) became a member of the enclosing namespace.
Function prototypes are hints for the compiler. They indicate that the functions are implemented somewhere else, if not already discovered. Nothing more.
When you declare a prototype as you are doing you are basically telling the compiler to wait for the linker to resolve it. Depending where you write the prototype the scoping rules apply. There is nothing technically wrong writing the prototype inside your main() function (although IMHO a bit messier), it just means that the function is only locally known inside the main(). If you would have declared the prototype at the top of your source file (or more commonly in a header file), the prototype/function would be known in the whole source.
string foo()
{
string ret = someString(); // Error
return ret;
}
int main(int argc,char**argv)
{
string someString();
string s = somestring(); // OK
...
}