0

I am unit testing for code coverage, making sure that every possible code path is executed by a unit test.

I find that a switch/case element which merely contains a break can be breakpointed, but that the break is never hit, control just jumps to the end of the switch, presumably because of compiler optimization.

A colleague is arguing that that I have not adequately unit test that path.

So, I searched and found an S.O question - which I can not longer find - about C++ code that does nothing. The only answer that didn't also get optimized away of generate compiler or static code analysis errors was []() {}().

This works, insomuch as a breakpoint on it will be hit.

Problem solved, I guess, but what does that actually do?

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 1
    `[](){}` is a do nothing lambda function. And the extra `()` calls that function. Not sure why that could not be optimised away however. – john Aug 02 '22 at 06:17
  • [What does `[](){}` construction mean in c++?](https://stackoverflow.com/q/15389579/995714), [How is `int main(){(([](){})());}` valid C++?](https://stackoverflow.com/q/13603286/995714), [What is a lambda expression in C++11?](https://stackoverflow.com/q/7627098/995714) – phuclv Aug 02 '22 at 07:02
  • 1
    For your colleague, you could replace it with `<::>()<%%>();` which has the advantage of looking more bug-like. – Eljay Aug 02 '22 at 12:03
  • Lol! I like the look of that, but won't pretend that I understand it :-) – Mawg says reinstate Monica Aug 03 '22 at 07:43

1 Answers1

2

This is an empty lambda that gets executed and does nothing. Usually to set a breakpoint in debugging, at the end of a function or another code block.

[] () {   } ()
^^^ ------------------- no captures
   ^^^ ---------------- no parameters
        ^^^------------ function body
             ^^ ------- call operator (operator()) with no arguments.

Compare this with a Lambda that actually does something:

int x = 5;
auto lambda = [&x](int i){ x=x*i; };
lambda(2);
std::cout << "x is now: " << x << "\n"; // prints x=10

If a function gets optimised out or not is compiler specific.

I composed a small example on godbolt

#include <iostream>

inline void nothing(){}

int main(){
    int x = 5;
    [](){}();
    nothing();
    std::cout << x+3 << "\n";
}

Depending on the optimisation -O0 or -O1, ... and if the nothing() function is marked inline or not, you can see a difference in the assembly.

In gcc12.1 and -O1 the empty lambda is optimised out as well as the call to nothing(). If you remove the inline keyword, even the nothing() declaration disappears as well

infinitezero
  • 1,610
  • 3
  • 14
  • 29