sistema - simbolos matematicos en latex
¿Los paréntesis hacen una diferencia al determinar el tamaño de una matriz? (2)
A partir de C99, 6.5.1, en expresiones entre paréntesis:
Su tipo y valor son idénticos a los de la expresión sin paréntesis.
A primera vista, parece que esto entra en conflicto con la lista de excepciones a la que se refiere (6.3.2.1):
Excepto cuando es el operando del operador
sizeof
o el operador unario&
, o si se utiliza un literal de cadena para inicializar una matriz, una expresión que tiene el tipo "matriz de tipo" se convierte en una expresión con el tipo "puntero a tipo". ..
Sin embargo, esta lista está en el contexto de operadores / operandos; los paréntesis no parecen considerarse un operador (según la categorización implícita en la estructura de la sección 6.5).
El siguiente programa imprime el mismo número dos veces en gcc 4.8.2:
#include <stdio.h>
int main()
{
char a[13];
printf("sizeof a is %zu/n", sizeof a );
printf("sizeof(a) is %zu/n", sizeof(a));
}
De acuerdo con esta publicación de reddit , gcc no cumple con el estándar a este respecto, porque una expresión entre paréntesis no se encuentra en la lista de excepciones para cuando no se produce la desintegración de matriz a puntero.
¿Es este tipo correcto? Aquí está la cita estándar relevante:
Excepto cuando es el operando del operador
sizeof
o el operador unario&
, o si se utiliza un literal de cadena de caracteres para inicializar una matriz de tipo de caracteres, o si se usa un literal de cadena ancha para inicializar una matriz con el tipo de elemento compatible conwchar_t
, un lvalue que tiene el tipo ''matriz de tipo'' se convierte en una expresión que tiene tipo ''puntero a tipo'' que apunta al miembro inicial del objeto de matriz y no es un lvalue.
Para que quede claro, argumenta que (a)
debe desencadenar la caída de matriz a puntero, porque los paréntesis no están cubiertos en la lista anterior (operador de sizeof
, unary &
operator, literal de cadena como inicializador).
Si los paréntesis aparentemente redundantes afectan la semántica de un programa es un problema de larga data en el estándar C que aún no se ha resuelto adecuadamente.
Comúnmente se afirma que ((void*)0)
técnicamente no es una constante de puntero nulo, porque no hay una regla que diga que una constante de puntero nulo entre paréntesis es una constante de puntero nula.
Algunos compiladores emiten un error para char s[] = ("abc");
, porque mientras una matriz de caracteres puede inicializarse desde un literal de cadena, esa regla no cubre los literales de cadena entre paréntesis.
Hay muchos ejemplos similares. Has encontrado uno de ellos.
Por lo que puedo decir, el consenso es básicamente que la regla debería ser lo que hace C ++, pero lo que C nunca adoptó formalmente. C ++ hace que una expresión entre paréntesis sea funcionalmente equivalente a la expresión no entre paréntesis, con algunas excepciones explícitas. Esto cubriría todos esos problemas a la vez.
Así que técnicamente, el chico podría considerarse correcto, pero es una interpretación demasiado estricta de la norma que nadie realmente sigue, ya que se sabe que la norma es simplemente defectuosa aquí.