He heredado un programa C++ muy antiguo (+15 años) que actualmente se ejecuta en AIX usando el compilador xlc de IBM. Encontré una declaración de cambio y no entiendo cómo funcionó esto.
A continuación se muestra un ejemplo mínimo que muestra la situación.
#include <iostream> using namespace std; int main() { int i=5; switch( i ) { case 1: cout << "case " << i << endl; break; case 2: cout << "case " << i << endl; break; Otherwise: cout << "case " << i << endl; break; } cout << "bye\n"; }Estoy usando GCC 7.3.1 en Amazon Linux 2. El programa se compila bien y muestra que este resultado es:
byeSi agrego "-Wall", entonces me dice lo siguiente:
minex.C: In function 'int main()': minex.C:15:3: warning: label 'Otherwise' defined but not used [-Wunused-label] Otherwise: ^~~~~~~~~Preguntas:
¿Por qué no es esto un error de sintaxis?
¿Las etiquetas de los casos no tienen que seguir la forma "caso n:" donde n es una expresión entera o "predeterminado:" (o una expresión de cadena constante, pero eso no parece relevante aquí?
¿Puede alguien señalarme una referencia que diga que se supone que esto está permitido?
Una etiqueta puede ocurrir en cualquier declaración. Que la declaración esté dentro de un bloque de switch no importa. Se puede saltar a esta etiqueta desde cualquier lugar dentro de la función actual.
Una etiqueta de case o default solo puede aparecer dentro de un switch , pero eso no impide que otras etiquetas aparezcan allí también.
La sección 9.1 del estándar C++17 describe declaraciones etiquetadas:
1 Una declaración puede ser etiquetada.
declaración etiquetada:
atributo-especificador-seq opt identificador: declaración
atributo-especificador-seq opt case expresión-constante : instrucción
atributo-especificador-seq opt predeterminado : declaración
El atributo-especificador-seq opcional pertenece a la etiqueta. Una etiqueta de identificador declara el identificador. El único uso de una etiqueta de identificador es como destino de un
goto. El alcance de una etiqueta es la función en la que aparece. Las etiquetas no se volverán a declarar dentro de una función. Se puede usar una etiqueta en una instruccióngotoantes de su declaración. Las etiquetas tienen su propio espacio de nombres y no interfieren con otros identificadores. [ Nota: una etiqueta puede tener el mismo nombre que otra declaración en el mismo ámbito o un parámetro de plantilla de un ámbito adjunto. La búsqueda de nombres no calificados (6.4.1) ignora las etiquetas. - nota final]2 Las etiquetas de caso y las etiquetas predeterminadas solo aparecerán en sentencias de cambio
Tenga en cuenta que existen restricciones sobre case y default , pero no sobre otras etiquetas.