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.
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.
1
2
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
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.