1

I'm currently doing some research on the STL, especially for printing the STL content during debug. I know there are many different approaches.

Like:

What I'm currently looking for is, why g++ deletes functions, which are not used for example I have following code and use the compile setting g++ -g main.cpp -o main.o.

include <vector>
include <iostream>
using namespace std;
int main() {
    std::vector<int> vec;
    vec.push_back(10);
    vec.push_back(20);
    vec.push_back(30);

    return;
}

So when I debug this code I will see that I can't use print vec.front(). The message I receive is:

Cannot evaluate function -- may be inlined

Therefore I tried to use the setting -fkeep-inline-functions, but no changes.

When i use nm main.o | grep front I see that there is no line entry for the method .front(). Doing the same again but, with an extra vec.front() entry within my code I can use print vec.front(), and using nm main.o | grep front where I see the entry

0000000000401834 W _ZNSt6vectorIiSaIiEE5frontEv

Can someone explain me how I can keep all functions within my code without loosing them. I think, that dead functions do not get deleted as long as I don't set optimize settings or do following.

Why I need it: Current Python implementations use the internal STL implementation to print the content of a container, but it would be much more interesting to use functions which are defined by ISO/IEC 14882. I know it's possible to write a shared library, which can be compiled to your actual code before you debug it, to maintain that you have all STL functions, but who wants to compile an extra lib to its code, before debugging. It would also be interesting to know if there are some advantages and disadvantages of this two approaches (Shared Lib. and Python)?

Community
  • 1
  • 1
ManIHang
  • 13
  • 4
  • 2
    There has been an answer given to your question: http://stackoverflow.com/a/7241548/184968."`Partial instantiation`" : `... only the member functions that are used are instantiated. The following is well-formed code:`. I mean than you are asking about "dead function", but std::vector::front() is a member of template. It has not been deleted, it was not even created in your example. –  Jun 09 '12 at 11:45
  • Sorry for the misunderstanding. In the paragaph "**When i use "nm main.o | grep front" etc...**, I tried to say that after using vec.front() within my Code I where able to use the function within gdb. What's exactly a dead function, isn't it a function which is available in my source code but isn't used?? Another question does gdb know about the function .front(), eventhough I didn't use it, but has no debug informations? – ManIHang Jun 09 '12 at 12:22

2 Answers2

4

What's exactly a dead function, isn't it a function which is available in my source code but isn't used?

There are two cases to consider:

int unused_function() { return 42; }
int main() { return 0; }

If you compile above program, the unused_function is dead -- never called. However, it would still be present in the final executable (even with optimization [1]).

Now consider this:

template <typename T> int unused_function(T*) { return 42; }
int main() { return 0; }

In this case, unused_function will not be present, even when you turn off all optimizations.

Why? Because the template is not a "real" function. It's a prototype, from which the compiler can create "real" functions (called "template instantiation") -- one for each type T. Since you've never used unused_function, the compiler didn't create any "real" instances of it.

You can request that the compiler explicitly instantiate all functions in a given class, with explicit instantiation request, like so:

#include <vector>
template class std::vector<int>;

int main() { return 0; }

Now, even though none of the vector functions are used, they are all instantiated into the final binary.

[1] If you are using the GNU ld (or gold), you could still get rid of unused_function in this case, by compiling with -ffunction-sections and linking with -Wl,--gc-sections.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
0

Thanks for your answer. Just to repeat, template functions don't get initiated by the gcc, because they are prototypes. Only when the function is used or it gets explicitly initiated it will be available within my executable.

So what we have mentioned until yet is :

  • function definition int unusedFunc() { return 10; }
  • function prototype int protypeFunc(); (just to break it down)

What happens when you inline functions? I always thought, that the function will be inserted within my source code, but now I read, that compilers often decide what to do on their own. (Sounds strange, because their must be rule). It doesn't matter if you use the keyword inline, for example.

inline int inlineFunc() { return 10; }

A friend of mine also told me that he hasn't had access to addresses of functions, although he hasn't used inline. Are there any function types I forgot? He also told me that their should be differences within the object data format.

@edit - forgot:

  • nested functions
  • function pointers
  • overloaded functions
ManIHang
  • 13
  • 4