Dear Readers!
As a first post of the year, I’m going to discuss something light and easy, a tiny optimization effort around switch statements involving additional variables. So here it goes: as I was doing my usual practice coding, I encountered an interesting situation, that probably people wouldn’t even try too many times because of the tiny performance boost it usually provides. But because there could be cases when one needs this optimization and I was curious about it, I went ahead and tried to make it work. Here is my original try:
C++
1
2
3
4
5
6
7
8
9
10
// ...
switch (event) {
case cv::EVENT_FLAG_LBUTTON:
pixelColors = getPixelColorCode(*img, x, y);
std::string colorMessage = generatePixColorText(pixelColors);
// ...
default:
// ...
The above code throws the following error:
Make
1
2
3
4
error: jump to case label [-fpermissive]
default:
note: crosses initialization of ‘std::__cxx11::string colorMessage’
std::string colorMessage = generatePixColorText(pixelColors);
What I tried to do here is to create that string only in case event
was equal to cv::EVENT_FLAG_LBUTTON
, so that I do not waste cycles on creating it when otherwise it is not needed. Of course, it didn’t work and the compiler didn’t help much with that error message either. The situation seems to be (this is just a guess, I didn’t invest time into investigating this thoroughly), that none of the cases in the switch
statement have their own scope, and this somehow prevents the compiler to allocate space for the variable and initialize it in the same time. Interestingly, if one simply declares that string but doesn’t initialize it, the program compiles just fine (although the string is not really useful then). On the other hand, if one would move the declaration of the string outside of the switch
statement and then initialize it at the desired case, it of course compiles again:
C++
1
2
3
4
5
6
7
8
9
10
11
// ...
std::string colorMessage;
switch (event) {
case cv::EVENT_FLAG_LBUTTON:
pixelColors = getPixelColorCode(*img, x, y);
colorMessage = generatePixColorText(pixelColors);
// ...
default:
// ...
But this is precisely what I wanted to avoid, maybe because we are using a different type, that is far more expensive to create. So what can be done if we really need that optimization? Well, using a bit of additional scoping seems to be able to solve our problem, as the compiler is now happy:
C++
1
2
3
4
5
6
7
8
9
switch (event) {
case cv::EVENT_FLAG_LBUTTON: {
pixelColors = getPixelColorCode(*img, x, y);
std::string colorMessage = generatePixColorText(pixelColors);
// ...
}
default:
// ...
So the lesson of the day is:
One cannot simultaneously declare and define a variable inside a switch statement, unless one uses additional scoping.
As always, thanks for reading.