Click here to Skip to main content
15,892,072 members
Articles / All Topics

A Workaround for Lambda ODR Violations

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
13 Jan 2016CPOL1 min read 5.2K   1  
A workaround for Lambda ODR violations

As brought up in this post with lambdas in inline functions, you can run into ODR violations and thus undefined behavior.

There is also a stack overflow discussion here.

While the ultimate fix may rely on the Core Working Group, I think here is a workaround.

The basis for the trick comes from Paul Fultz II in a post about constexpr lambda. You can find the post here.

Here is some problematic code from the stackoverflow discussion. The lambda may have a different type across translation units and thus result in different specializations of for_each being called for different translation units resulting in ODR violations and thus undefined behavior.

C#
  1  inline void g() {
  2      int arr[2] = {};
  3      std::for_each(arr, arr+2, [] (int i) {std::cout << i << ' ';});
  4  }

Here is a simple fix that will prevent the ODR violation.

C#
  1  // Based on Richard Smith trick for constexpr lambda
  2  // via Paul Fultz II (http://pfultz2.com/blog/2014/09/02/static-lambda/)
  3  template<typename t="">
  4  auto addr(T &&t)
  5  {
  6      return &t;
  7  }
  8  
  9  static const constexpr auto odr_helper = true ? nullptr : addr([](){});
 10  
 11  template <class t="decltype(odr_helper)">
 12  inline void g() {
 13      int arr[2] = {};
 14      std::for_each(arr, arr+2, [] (int i) {std::cout << i << ' ';});
 15  }

We create a static const constexpr null pointer with the type of a lambda. If lambdas are different types across different translation units, then odr_helper will have different types across different translation units. Because g now is a template function using the type of odr_helper, g will be a different specialization across different translation units and thus will not result in an odr violation.

Also note that because T is defaulted, g can be used without any changes from before.

ideone at https://ideone.com/NdBpXN

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer self employed
United States United States
I started programming in Basic in the 4th grade. In 8th grade, I convinced my parents to buy me Visual C++ 1.0. I discovered I really enjoyed C++, and have been programming in it since. I attended the University of Florida and majored in Computer Science graduating with honors with a 4.0 GPA. I then attending Medical School and obtained my Doctor of Medicine degree.

I have used my computer skills to help me in my medical practice. I also enjoy programming in C++ just for fun, trying to discover new ways of solving problems or applying C++ to new areas. My latest interest has been in creating a component system for C++ allowing components created with 1 compiler to be easily used by another compiler.

Comments and Discussions

 
-- There are no messages in this forum --