Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

143
Vistas
const/static/volatile en la especificación de tipo de matriz?

¿Qué define la siguiente firma de función en C?

 #include <stdio.h> #include <string.h> void f(int a[const volatile static 2]) { (void)a; } int main() { int b[1]; f(b); }

https://godbolt.org/z/6qPxaM1vM

No entiendo el significado de const / volatile / static en este lugar, pero parece compilarse, así que supongo que tiene un significado.

Gracias

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Un parámetro de tipo matriz se ajusta automáticamente a un tipo de puntero. Por lo tanto, un parámetro declarado como:

 int A[3]

se transforma en:

 int *A

Sin embargo, con la notación de matriz no hay un lugar intuitivo para agregar el calificador de la variable a sí misma (no los datos señalados por a ). Por lo tanto, el estándar C permite poner esos especificadores entre paréntesis.

Por lo tanto:

 void f(int a[const volatile restrict 2])

es en realidad:

 void (int * const volatile restrict a)

El tamaño ( 2 en el ejemplo anterior) generalmente se ignora. La excepción es cuando se usa una palabra clave static . Proporciona una pista para un compilador de que al menos los elementos en las direcciones a + 0 a a + size - 1 son válidos. Esta sugerencia en teoría debería mejorar la optimización al simplificar la vectorización. Sin embargo, AFAIK es ignorado por los principales compiladores.

Tu codigo:

 int b[1]; f(b);

está activando UB porque solo el elemento en la dirección b + 0 es válido, mientras que la sugerencia requiere que b+0 y b+1 sean válidos. Los mejores compiladores/desinfectadores deberían detectar eso.

La static también es útil para la autodocumentación y la detección de errores, como decir que al menos n elementos señalados por un puntero deben ser válidos:

 void fun(int n, int arr[static n])

o incluso decir que el puntero nunca es NULL :

 void fun(int ptr[static 1]);

Además, la sintaxis int buf[static n] es una buena pista visual de que algo en realidad no es una matriz. Ayuda a evitar un error común al intentar adquirir el tamaño de una "matriz" con la sintaxis sizeof buf .


EDITAR

Como se indica en el comentario, la palabra "sugerencia" puede ser un poco engañosa porque podría interpretarse que la violación de la "sugerencia" no es un error, aunque puede resultar en algo no óptimo (como la degradación del rendimiento). En realidad, es más bien un requisito, cuya violación da como resultado un comportamiento indefinido.

over 4 years ago · Santiago Trujillo Denunciar

0

Esta es una característica levemente útil introducida en C99. Desde C17 6.7.6.3/7:

La declaración de un parámetro como "matriz de tipo" se ajustará a "puntero calificado a tipo", donde los calificadores de tipo (si los hay) son los especificados entre [ y ] de la derivación del tipo de matriz. Si la palabra clave static también aparece dentro de [ y ] de la derivación del tipo de matriz, entonces, para cada llamada a la función, el valor del argumento real correspondiente proporcionará acceso al primer elemento de una matriz con al menos tantos elementos como se especifica por la expresión de tamaño.

Es decir, en este caso, los calificadores const y volatile significan que la matriz se descompone en un puntero de tipo int* const volatile a . Dado que este tipo calificado es local para la función, significa muy poco para la persona que llama, ya que un puntero pasado se asigna mediante la conversión de lvalue y aún puede ser un tipo de puntero no calificado.

El static es un poco más útil, ya que supuestamente permite que el compilador verifique el tamaño en tiempo de compilación, aunque en la práctica parece que los compiladores principales (actualmente) solo logran verificar que el puntero no sea nulo. Por ejemplo f(0) en clang da:

advertencia: nulo pasado a un destinatario que requiere un argumento no nulo [-Wnonnull]

Curiosamente, f(0) en gcc 11.1 y posteriores dice:

advertencia: el argumento 1 a 'int[static 8]' es nulo donde no se esperaba [-Wnonnull]"

No tengo idea de dónde proviene el 8 , supongo que es un error tipográfico/menor del compilador (el puntero deteriorado tiene un tamaño de 8 bytes).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda