15

Our logging framework, like most logging frameworks, uses the __FUNCTION__ preprocessor macro to insert the current function into log files so that our logging looks like:

L4  T11332 609661594 [PreProcessorFunctions::RegenerateLinkIDs] [ENTER]
L4  T11332 609661594 [PreProcessorFunctions::RegenerateLinkIDs] [EXIT]
L4  T11332 609661594 [ConfigMerger::ValidateConfigObject] [ENTER]
L3  T11332 609661594 [ConfigMerger::ValidateConfigObject] Configuration Exists: 1

As we've started to use C++11 more, I've noticed that labmdas produce accurate yet unhelpful __FUNCTION__ output:

L4  T9604 609661594 [`anonymous-namespace'::<lambda1>::operator ()] Writing EMX config file: C:\windows\TEMP\CBE01448-32A2-493A-A9A1-2112F5709028\CA37BE5C-B398-4D61-980D-66B8E1E6D001\\EMXConfiguration.xml
L4  T11332 609661594 [`anonymous-namespace'::<lambda3>::operator ()] Writing Auditing config file: C:\windows\TEMP\CBE01448-32A2-493A-A9A1-2112F5709028\CA37BE5C-B398-4D61-980D-66B8E1E6D001\\Auditing.xml
L4  T11960 609661594 [`anonymous-namespace'::<lambda2>::operator ()] Writing UEM config file: C:\windows\TEMP\CBE01448-32A2-493A-A9A1-2112F5709028\CA37BE5C-B398-4D61-980D-66B8E1E6D001\\Configuration.xml

As you can see, all class scope has been lost and all we now know is that this logging statement came from an anonymous lambda. Does anyone have a good strategy for logging out the enclosing function? This would appear to be the most useful thing to log...

Benj
  • 31,668
  • 17
  • 78
  • 127
  • http://stackoverflow.com/questions/4434282/visual-c-equivalent-of-file-line-and-pretty-function What does `__FUNCSIG__` give for lambdas? – BoBTFish Oct 04 '12 at 13:40
  • Haha, VS2012 shows: `wmain::::operator ()` – Benj Oct 04 '12 at 13:48
  • At least it does show the enclosing function... – Benj Oct 04 '12 at 13:48
  • VS2012 produces similar output for `__FUNCTION__` as well, it is somewhat more helpful since at least it could be manipulated into something helpful in the logs. – Benj Oct 04 '12 at 13:52

1 Answers1

13

I think the only workaround would be to expand __FUNCTION__ (or __func__ in C++11) in the enclosing function and capture that inside the lambda.

void f(){
  auto& _func_ = __func__;
  [&]{ std::cout << _func_; };
}

I would tag this as a "quality of implementation" issue, though. GCC, for example, provides the __PRETTY_FUNCTION__ macro that expands much better for lambdas (and in general):

#include <iostream>

struct X{
  void f(){
    []{ std::cout << __PRETTY_FUNCTION__ << "\n"; }();
  }
};

int main(){
  X().f();
}

Output: X::f()::<lambda()>

Live example.

dashesy
  • 2,596
  • 3
  • 45
  • 61
Xeo
  • 129,499
  • 52
  • 291
  • 397