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

185
Vistas
¿Es esto escribir en una matriz un comportamiento verdaderamente indefinido en C?

Este código escribe un valor a través de un puntero si una matriz está más allá del final de otra matriz.

 #include <stdio.h> #include <inttypes.h> extern int first[], second[]; #define ADDR_AFTER(ptr) ((uintptr_t)((ptr) + 1)) int test(int *an_int) { *second = 1; if (ADDR_AFTER(first) == (uintptr_t)an_int) { // ubsan does not like this. *an_int = 2; } return *second; } int first[1] = {0}, second[1] = {0}; int main() { if (ADDR_AFTER(first) == (uintptr_t)second) { printf("test: %d\n", test(second)); printf("x: %dy: %d\n", *first, *second); } }

En ningún momento comparo directamente dos punteros con diferentes objetos (porque primero los convierto a uintptr_t ). Creo un puntero a uno más allá del final de una matriz (lo cual es legal), pero nunca elimino la referencia de ese puntero. Por lo que puedo decir, esto no debería imprimir nada o imprimir:

prueba: 2
x: 0 y: 2

Que se imprime en Clang cuando la optimización es -O1 o inferior. En -O2 , sin embargo, imprime:

prueba: 1
x: 0 y: 2

Con -O2 -fsanitize=undefined imprime esto en la salida estándar:

prueba: 2
x: 0 y: 2

y lo siguiente a stderr:

error de tiempo de ejecución: almacene en la dirección 0x000000cd9efc con espacio insuficiente para un objeto de tipo 'int'
0x000000cd9efc: nota: el puntero apunta aquí
  00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

con una referencia a la asignación a an_int en test . ¿Es este un comportamiento indefinido o es un error en Clang?

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

0

No hay nada inválido en su código, el compilador está mal. Si elimina la verificación ADDR_AFTER innecesaria en test() , el código se ejecuta como se esperaba sin ningún error UBSan. Si lo ejecuta con la optimización habilitada y sin UBSan, obtendrá un resultado incorrecto (prueba = 1, debería ser 2).

Algo sobre el ADDR_AFTER(first) == (uintptr_t)an_int dentro test() hace que Clang haga algo incorrecto al compilar con -O2 .

Probé con Apple clang version 11.0.3 (clang-1103.0.32.62) pero parece que Clang 13 y el tronco actual también tienen el error: https://godbolt.org/z/s83ncTsbf - si cambia el compilador a cualquier versión de GCC verás que puede devolver 1 o 2 desde main() , mientras que Clang siempre devuelve 1 ( mov eax, 1 ).

Probablemente deberías presentar un error de Clang para esto.

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