Liebe Leserinnen, liebe Leser,
als der erste Beitrag des Jahres möchte ich über etwas Einfaches, genauer ausgedrückt über eine kleine Optimierung in switch-Anweisungen mit zusätzlichen Variablen diskutieren. Los geht’s: Als ich meine gewöhnliche Übungskodierung gemacht habe, habe ich eine interessante Situation begegnet, die Leute wegen der kleinen erreichbaren Leistungserhöhung vielmals wahrscheinlich nicht ausprobieren. Weil es Fälle geben könnten, wenn man diese Optimierung braucht, und ich war sehr neugierig, versuchte ich das funktionierbar zu machen. Hier ist mein ursprünglicher Versuch:
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:
// ...
Dieser Code erzeugt die folgende Fehlermeldung:
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);
Ich versuchte den String nur in dem Fall erstellen, wenn event mit cv::EVENT_FLAG_LBUTTON gleich war, sodass keine Prozessorzyklen für die Erstellung von string verschwendet werden. Natürlich funktionierte es nicht, und der Compiler war mit der Fehlermeldung auch nicht so hilfreich. Die Situation scheint so zu sein (das ist nur eine Vermutung, ich hatte keine Zeit für eine umfangreiche Untersuchung), dass in der switch-Anweisung ein case keinen eigenen Bereich hat, und das verhindert irgendwie die gleichzeitige Speicherzuteilung und Initialisierung der Variable. Interessanterweise, falls man den String nur deklariert aber nicht initialisiert, wird das Programm ohne Aufwand kompiliert werden (obwohl der string auf diese Weise nicht so nutzbar ist). Andererseits, falls der String außerhalb der switch-Anweisung deklariert und dann in den beliebigen case initialisiert wird, wird die ganze Sache wieder kompilierbar sein.
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:
// ...
Aber ich wollte genau diese Sache vermeiden, weil vielleicht die Nutzung von einem anderen teurer erstellbaren Typ erwünscht ist. Was kann dann gemacht werden, wenn man diese Optimierung wirklich braucht? Die Nutzung von zusätzlichen Scoping scheint unseres Problem zu lösen, weil der Compiler nun zufrieden ist:
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:
// ...
Also, die Lektion des Tages ist:
Die gleichzeitige Deklaration und Initialisierung einer Variable in einer switch-Anweisung nicht möglich ist, es sei denn zusätzliche Scoping ist benutzt.
Wie immer, vielen Dank fürs Lesen.