Estaba practicando C y encontré un programa que usa operadores aritméticos en declaraciones de case . Pero he aprendido que las operaciones aritméticas no se pueden usar en ese lugar.
Entonces, ¿cómo funciona este programa?
#include <stdio.h> int main() { int ch = 'a' + 'b'; switch (ch) { case 'a': case 'b': printf("You entered b \n"); case 'A': printf("a as in ashar \n"); case 'b'+'a': printf("You entered a and b \n"); } return (0); } Según yo, la variable ch almacenará valores ASCII del carácter 'a' + 'b' , es decir, ch = 97 + 98 que se convierte en ch = 195;
El switch(ch) coincidirá con el caso con 195, es decir, case 'a' + 'b' .
Pero el problema es ¿cómo podemos usar operadores case contra las reglas del lenguaje C?
No se permiten ningún problema siempre que sean expresiones constantes enteras .
Del estándar C99 § 6.8.4.2 punto 3:
La expresión de cada etiqueta de
caseserá una expresión entera constante (...)
Y el § 6.6 punto 6 lo describe así:
Una expresión de constante entera tendrá un tipo entero y solo tendrá operandos que sean constantes enteras, constantes de enumeración, constantes de caracteres, expresiones
sizeofcuyos resultados sean constantes enteras y constantes flotantes que sean los operandos inmediatos de las conversiones. Los operadores de conversión en una expresión constante entera solo convertirán tipos aritméticos en tipos enteros, excepto como parte de un operando en el operadorsizeof.
Y el § 6.6 punto 2 dice:
Una expresión constante se puede evaluar durante la traducción en lugar del tiempo de ejecución y, en consecuencia, se puede usar en cualquier lugar donde se encuentre una constante.
En el § 6.2.5 punto 14 leemos:
El tipo
char, los tipos enteros con y sin signo y los tipos enumerados se denominan colectivamente tipos enteros. Los tipos flotantes enteros y reales se denominan colectivamente tipos reales.
Y también en el § 6.4.4.4 punto 2:
Una constante de carácter entero es una secuencia de uno o más caracteres multibyte encerrados entre comillas simples, como en
'x'. (...)
Todos los elementos de la expresión 'a' + 'b' se conocen en tiempo de compilación.
Los valores escritos entre comillas simples son números enteros, por lo que los caracteres también son solo números enteros.
El compilador puede evaluar la expresión y simplemente reemplazarla con el 195 resultante.
No hay nada en el lenguaje que impida usar el operador + en un case .
El requisito es que el valor del caso sea una expresión constante entera . Dicha expresión no puede contener un operador de asignación, incremento, decremento, llamada de función o coma, pero se permiten otros operadores siempre que cada subexpresión sea una constante.
La sección 6.8.4.2p3 del estándar C describe los requisitos para un case :
La expresión de cada etiqueta de
caseserá una expresión constante entera y dos de las expresiones constantes decaseen la misma declaración deswitchno tendrán el mismo valor después de la conversión.
La Sección 6.6p6 describe una expresión constante entera:
Una expresión de constante entera tendrá un tipo entero y solo tendrá operandos que sean constantes enteras, constantes de enumeración, constantes de caracteres, expresiones
sizeofcuyos resultados sean constantes enteras, expresiones_Alignofy constantes flotantes que sean los operandos inmediatos de las conversiones. Los operadores de conversión en una expresión constante entera solo convertirán tipos aritméticos en tipos enteros, excepto como parte de un operando al operadorsizeofo_Alignof.
Y la sección 6.6p3 describe las restricciones de los operadores en una expresión constante:
Las expresiones constantes no deben contener operadores de asignación, incremento, decremento, llamada de función o coma, excepto cuando están contenidos dentro de una subexpresión que no se evalúa.
Según la norma (C99)
La expresión de cada etiqueta de caso será una expresión constante de entero y dos de las expresiones de constante de caso en la misma declaración de cambio no tendrán el mismo valor después de la conversión. Puede haber como máximo una etiqueta predeterminada en una declaración de cambio. (Cualquier declaración de cambio adjunta puede tener una etiqueta predeterminada o expresiones constantes de mayúsculas y minúsculas con valores que duplican las expresiones constantes de mayúsculas y minúsculas en la declaración de cambio adjunta).
Una expresión constante se puede evaluar durante la traducción en lugar del tiempo de ejecución y, en consecuencia, se puede usar en cualquier lugar donde se encuentre una constante.
La expresión 'b'+'a' se traducirá en tiempo de compilación y, por lo tanto, es una expresión constante que, como ha notado, se evalúa como 195.