Question

If I have a function A(), I am interested in finding a convenient method to create a function B() that has the exact same functionality as A(), differing only in name. The new function would be for a one-time use. The intent is to differentiate between calls to the same function in a somewhat primitive sampling profiler, and the duplicated function would only be used in this context. That is, it would never touch production code and only be used for tinkering.

First guess would be a macro that declares a function named B and creates an inlined call to A() inside of it. The problem here is that I'm not aware of a method in GCC to force an arbitrary function call to inline; it seems all inlining options are for function declarations rather than calls.

There may be some esoteric way to do it with templates, or possibly by tricking the compiler into inlining. I'm not sure it's possible. Any thoughts? Unfortunately the new C++ standard is not available, if it would make a difference.

Was it helpful?

Solution

Using templates

template<int x>
void A()
{
    // ..
}

int main()
{
    A<0>();
    A<1>();
    return 0;
}

Update

The compiler can be too smart and create only one body for A<0> and A<1>. At least Visual C++ 2010 does it in Release mode. To prevent it, just use the template parameter inside the function template body in logs or asserts. For example,

#include <iostream>

template<int x>
void A()
{
    ::std::cout << x << std::endl;
    // ..
}

int main()
{
    A<0>();
    A<1>();
    auto v0 = A<0>;
    auto v1 = A<1>;
    ::std::cout << v0 << std::endl;
    ::std::cout << v1 << std::endl;
    ::std::cout << (v0 == v1) << std::endl;
    return 0;
}

OTHER TIPS

This works using templates:

#include <iostream>                                                             

template<typename T>
void foo() {
    static int x = 0;
    std::cout << &x << std::endl;
}

int main(int argc, char **argv) {
    foo<int>();
    foo<float>();
    return 0;
}

If you execute that, you'll see two different values printed, reflecting the compiler generated code for both calls, even though the template parameter is unused. nm on the object file confirms this.

If this is a one-time debug hack, then why not:

#define A_CONTENT \
    ... // whatever

void A()
{
    A_CONTENT
}

void B()
{
    A_CONTENT
}

...

A();  // Call to A
B();  // Call to B  

Macros are generally grim, but we're not talking about production code here, so who cares?

Having been down this road myself, the short answer is that even if you get the compiler to emit two identical duplicates of a function, the optimizing linker will notice that they're identical and fold them back together into one implementation. (And if you've turned off optimization in the linker, then your profile isn't valid anwyay).

In the context of a sampling profiler, I've found the easier approach is to make two tiny wrappers for the function instead:

void Func() { .... }

_declspec(noinline) 
void A_Func( return Func(); }
void B_Func( return Func(); }
void C_Func( return Func(); }

Then when your profiler samples the callstack, you'll be able to differentiate between the different callsites of this function in a very straightforward way..

You could always define a macro, for example in Chromium we do the following to reuse code:

#define CHROMEG_CALLBACK_1(CLASS, RETURN, METHOD, SENDER, ARG1)     \
  static RETURN METHOD ## Thunk(SENDER sender, ARG1 one,            \
                                gpointer userdata) {                \
    return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one); \
  }                                                                 \
                                                                    \
  virtual RETURN METHOD(SENDER, ARG1);

And we call them like:

 CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent, GdkEventExpose*);

 CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed, GdkEventButton*);

You can do something similar to do what you wanted. The above example shows us using two different implementations but with one common code base. For GTK callbacks.

It's a little unclear what you're really trying to do, but a really ugly solution would be to declare the body of A as a macro and then you can "inline" this macro within whatever functions you like.

Also, macros are evil. Never use them unless you really have to.

Why do you care so much about inlining it? If you create a wrapper function, there is a pretty good chance the compiler will inline it anyway. At the very least, you're unlikely to get a function frame constructed.

C++11 also lets you do this:

void A() {
    ...
}

...

auto B = [] () -> void { A(); };

You can now use B syntactically as though it was a function wrapping A.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top