Según el estándar C11, capítulo §5.1.1.2, concatenación de cadenas literales adyacentes:
Los tokens literales de cadenas adyacentes están concatenados.
ocurre en la fase de traducción . Por otra parte:
printf("Hi" (test ? "Bye" : "Goodbye"));
involucra al operador condicional, que se evalúa en tiempo de ejecución . Entonces, en tiempo de compilación, durante la fase de traducción, no hay presentes literales de cadena adyacentes, por lo que la concatenación no es posible. La sintaxis no es válida y, por lo tanto, su compilador la informa.
Para desarrollar un poco la parte del por qué , durante la fase de preprocesamiento, los literales de cadena adyacentes se concatenan y representan como un literal de cadena única (token). El almacenamiento se asigna en consecuencia y el literal de cadena concatenado se considera como una sola entidad (un literal de cadena).
Por otro lado, en caso de concatenación en tiempo de ejecución, el destino debe tener suficiente memoria para contener la cadena literal concatenada; de lo contrario, no habrá forma de que se pueda acceder a la salida concatenada esperada . Ahora, en el caso de los literales de cadena , que están ya asignados de memoria en tiempo de compilación y no pueden ser extendidos a presión en cualquier entrada más entrante en o añadidos a los contenidos originales. En otras palabras, no habrá forma de que se pueda acceder (presentar) al resultado concatenado como un solo literal de cadena . Entonces, esta construcción es intrínsecamente incorrecta.
Solo para su información, para la concatenación de cadenas en tiempo de ejecución ( no literales ), tenemos la función de biblioteca strcat()
que concatena dos cadenas . Aviso, la descripción menciona:
char *strcat(char * restrict s1,const char * restrict s2);
La strcat()
función agrega una copia de la cadena apuntada por s2
(incluido el carácter nulo de terminación) al final de la cadena apuntada pors1
. El carácter inicial de s2
sobrescribe el carácter nulo al final de s1
. [...]
Entonces, podemos ver que s1
es una cadena , no una cadena literal . Sin embargo, dado que el contenido de s2
no se modifica de ninguna manera, puede ser un literal de cadena .