El resultado de b - a
solo se define cuando tanto a
como b
apuntan a elementos de la misma matriz de caracteres. Este requisito también se puede interpretar como a
y b
apuntando a bytes que pertenecen al mismo objeto, ya que cada objeto se puede reinterpretar como una matriz de caracteres.
De lo contrario, el resultado no está definido. Es decir. un intento de restar tales punteros da como resultado un comportamiento indefinido.
Cuando se define el resultado, tiene el tipo ptrdiff_t
. ptrdiff_t
es un nombre typedef y qué tipo se esconde detrás de ese typedef nombre está definido por la implementación. Sin embargo, se sabe que el tipo está firmado.
También tenga en cuenta que el lenguaje C no garantiza que ptrdiff_t
sea lo suficientemente grande como para contener el resultado de una resta, incluso si los punteros apuntan a los elementos de la misma matriz. Si los punteros están demasiado separados para el tipo ptrdiff_t
para acomodar el resultado, el comportamiento no está definido.
No hay especificador específica printf
formato para ptrdiff_t
incluso en C99, por lo que probablemente va a estar mejor convirtiéndola en una cantidad suficientemente grande de tipo entero con signo y usar un especificador de formato para ese tipo
printf("%ld\n", (long) (b - a));
Corrección : C99 tiene un modificador de longitud para ptrdiff_t
. La forma correcta de imprimir el resultado en C99 sería
printf("%td\n", b - a);
Tenga en cuenta que t
es un modificador de longitud. Se puede combinar con d
, o
, u
, x
o X
especificadores de conversión, dependiendo del formato de salida que desee obtener. En C89/90, aún deberá seguir utilizando un tipo de firma suficientemente grande.
P.S. Dijiste que no puedes imaginar que falle en una máquina de 32 bits o de 64 bits. De hecho, es muy fácil imaginarlo (o hacerlo) fallar. Verá que el ptrdiff_t
en una máquina de 32 bits suele ser del tipo de 32 bits. Como es un tipo firmado, solo tiene 31 bits disponibles para representar la magnitud del valor. Si toma dos punteros que están más separados (es decir, requiere 32 bits para representar la "distancia"), el resultado de b - a
se desbordará y no tendrá sentido.Para evitar esta falla necesitaría al menos 33-bit firmó ptrdiff_t
en una máquina de 32 bits, y al menos firmó 65-bit ptrdiff_t
en la máquina de 64 bits. Las implementaciones normalmente no hacen eso, solo usan el "permiso" del estándar para producir un comportamiento indefinido en el desbordamiento.
+1 Para las peculiaridades estándar de C, como una diferencia de puntero que no encaja dentro de un 'ptrdiff_t' (también puedo pensar en palabras mucho más desagradables que" caprichos "). –
Sí, resulta que 'PTRDIFF_MIN' /' PTRDIFF_MAX' podría ser tan pequeño como +/- 65536 (según la especificación). Sin embargo, las implementaciones que verifiqué no hicieron cosas locas como esas; en la práctica, parece improbable que surja algo extraño como ese. –
Consideraría una implementación donde 'ptrdiff_t' es más pequeño (ancho en bits) que el tamaño de matriz más grande inusualmente roto, e incluso implementaciones donde el número de * bits de valor * es menor (es decir, arreglos mayores que los elementos' SIZE_MAX/2' permitido) bastante peligroso ... –