3

Let suppose we have a C++ program where functions are defined, let's call it input.cpp.

Now, I have another C++ program retrieve.cpp that has to "retrieve" all the functions in input.cpp at runtime (or even its object file, if this can help!).

By "retrieving" I mean obtaining something like std::list<std::string> where each element is the header of the string, or std::list<std::function> or any other similar solution.

Having good performance in this process is important.

WHY I NEED IT: In this post I'm trying to map a subset of functions (user defined) to implement a memoization framework. As someone suggested in the comment, it could be more performant to map all the functions inside the target program. This question comes from the necessity to enumerate/indexing all the functions inside a program.

Community
  • 1
  • 1
justHelloWorld
  • 5,380
  • 5
  • 41
  • 97
  • 8
    What do you mean _retrieve the functions_? – πάντα ῥεῖ Apr 18 '16 at 10:24
  • 1
    You should clarify if you're looking at the source, or a compiled app. These two will have very different solutions. (respectively http://clang.llvm.org/doxygen/group__CINDEX__CPP.html and anything that reads object file symbols for example) – viraptor Apr 18 '16 at 10:25
  • Besides the fact that a compiler might remove non used functions and that it may also inline all calls to a certain function and remove the function itself, you cannot get a list of all defined functions in a compiled C++ program. – Pixelchemist Apr 18 '16 at 10:26
  • @Pixelchemist Well, you can use `nm` for executables compiled in debug mode. – πάντα ῥεῖ Apr 18 '16 at 10:29
  • @πάνταῥεῖ: Which is a platform dependant way and also gives you all symbols - not only function, doesn't it? The question suggests some kind of "desire for 'introspection'". – Pixelchemist Apr 18 '16 at 10:30
  • A C++ program isn't part of itself. That is, a program has no way of referring to itself in a way that allows you to inspect its own state. So your question is lacking a lot of details. – Kerrek SB Apr 18 '16 at 10:30
  • This sounds like it might be an XY problem (see my answer for a link to what this is if you're unfamiliar) – OMGtechy Apr 18 '16 at 10:34
  • @KerrekSB maybe I didn't get what you mean, but as you can see from the question, the "retrieve" program is different from the one that is retrievied – justHelloWorld Apr 18 '16 at 10:34
  • In that case it's unclear what you mean by "program". – Kerrek SB Apr 18 '16 at 10:35
  • Updated adding why I need it – justHelloWorld Apr 18 '16 at 10:45
  • Why the question is still on hold? I clearly stated why I need this, isn't that enough? :) – justHelloWorld Apr 19 '16 at 12:56

1 Answers1

3

You can find all the exporter symbols by looking at the contents of the object file. On Windows you can use a program such as dumpbin for this and on Linux, nm is the droid you're looking for.

This will not, however, show you the "internal" symbols; symbols not exported in the object file.

If you only want a specific subset of the functions and you control the source for them, you could probably write some kind of horrible macro to store the names of the functions somewhere (you'd have to change every function declaration you were interested in if you went down this route). I wouldn't recommend this at all, but it's there as a last resort.

If you're talking about runtime inspection, then you'll be sad there hear that C++ does not have any kind of built-in reflection. There are different degrees of meta-data that can be made available through libraries (see here, but fundamentally this is something that needs to happen inside the compiler as a lot of information is lost after that stage of translation.

If you need access to this information at runtime then your best bet is probably to "preprocess" the object files (using the object file inspection programs I mentioned earlier), write this to a file and then have your program read this file back in to build up the std::list you mention.

It's also worth asking yourself why you want to do this; there might be a far more appropriate solution out there for your real problem (see XY problem).

Update

Now you've updated your post with why you want to do this, it all makes a lot more sense. If you're looking to memoise function calls then you could take a look at perfect forwarding and variadic templates; you could store a "cache" of function parameters and return the result if it's already been called with that before.

You don't want to apply this globally, as some functions are not pure functions (i.e. they have side effects and memoising them could break a lot of code); make sure you let your user choose which functions are memoised.

Community
  • 1
  • 1
OMGtechy
  • 7,082
  • 8
  • 40
  • 76
  • Updated adding why I need it – justHelloWorld Apr 18 '16 at 10:45
  • @justHelloWorld much better, answer updated – OMGtechy Apr 18 '16 at 10:49
  • thanks for your update, but actually the problem of this question is not how to implement memoization for a specific function (which I already know how to do it), but how to "retrieve" all the functions in a C++ program, so I can enumerate them in a static array (read the question and the linked post for more info). – justHelloWorld Apr 19 '16 at 12:27
  • @justHelloWorld Indeed, I believe my answer covers that :) – OMGtechy Apr 19 '16 at 12:28
  • I'm sorry for my stupidity, but I don't get how perfect forwarding or variadic templates could help me in detecting all the functions in a C++ program. – justHelloWorld Apr 19 '16 at 12:55
  • @justHelloWorld those parts of just for help with memoisation, the rest of the answer is about collecting the functions. So if you're happy with how to memoise (and you say you are) then you can just ignore the "Update" section :) – OMGtechy Apr 19 '16 at 12:58