significado punteros perro meaning dogs array c++ c pointers

c++ - punteros - pointers significado



¿Cuál es el uso de intptr_t? (4)

¿Cuál es el uso de intptr_t?

Ejemplo de uso: orden de comparación.
La comparación de los indicadores de igualdad no es un problema.
Otras operaciones de comparación como >, <= pueden ser UB. C11dr §6.5.8 / 5 Operadores relacionales.
Entonces intptr_t a intptr_t primero.

[Editar] Nuevo ejemplo: ordene una matriz de punteros por valor de puntero.

int ptr_cmp(const void *a, const void *b) { intptr_t ia = (intptr) (*((void **) a)); intptr_t ib = (intptr) (*((void **) b)); return (ia > ib) - (ia < ib); } void *a[N]; ... qsort(a, sizeof a/sizeof a[0], sizeof a[0], ptr_cmp);

[Ejemplo anterior] Ejemplo de uso: Probar si un puntero es de una matriz de punteros.

#define N 10 char special[N][1]; // UB as testing order of pointer, not of the same array, is UB. int test_special1(char *candidate) { return (candidate >= special[0]) && (candidate <= special[N-1]); } // OK - integer compare int test_special2(char *candidate) { intptr_t ca = (intptr_t) candidate; intptr_t mn = (intptr_t) special[0]; intptr_t mx = (intptr_t) special[N-1]; return (ca >= mn) && (ca <= mx); }

Como comentó @M.M , es posible que el código anterior no funcione según lo previsto. Pero al menos no es UB. - Funcionalidad simplemente no portátil. Esperaba usar esto para resolver este problema .

Sé que es un tipo entero que se puede convertir a / desde el puntero sin pérdida de datos, pero ¿por qué querría hacer esto? ¿Qué ventaja tiene tener un tipo entero sobre void* para mantener el puntero y THE_REAL_TYPE* para la aritmética de punteros?

EDITAR
La pregunta marcada como "ya se ha preguntado" no responde a esto. La pregunta es si usar intptr_t como intptr_t general para void* es una buena idea, y las respuestas parecen ser "no usar intptr_t", por lo que mi pregunta sigue siendo válida: ¿Cuál sería un buen caso de uso para intptr_t ?


El tipo uintptr_t es muy útil al escribir código de administración de memoria. Ese tipo de código quiere hablar con sus clientes en términos de punteros genéricos (void *), pero internamente hace todo tipo de aritmética en las direcciones.

Puede hacer algunas de las mismas cosas operando en términos de char *, pero no de todo, y el resultado parece ser el pre-Ansi C.

No todos los códigos de administración de memoria utilizan uintptr_t; como ejemplo, el código del kernel BSD define un vm_offset_t con propiedades similares. Pero si está escribiendo, por ejemplo, un paquete malloc de depuración, ¿por qué inventar su propio tipo?

También es útil cuando tiene% p disponible en su printf, y está escribiendo un código que necesita imprimir variables integrales de tamaño de puntero en hexadecimal en una variedad de arquitecturas.

Considero que intptr_t es bastante menos útil, excepto posiblemente como una estación de paso al lanzar, para evitar la terrible advertencia sobre el cambio de firmeza y tamaño de entero en el mismo lanzamiento. (Escribir un código portátil que pase -Wall -Werror en todas las arquitecturas relevantes puede ser un poco difícil).


La razón principal es que no puede realizar una operación a nivel de bits en un void * , pero puede hacer lo mismo en un intptr_t .

En muchas ocasiones, donde necesita realizar una operación bitwise en una dirección, puede usar intptr_t .

Sin embargo, para las operaciones bitwise, el mejor enfoque es utilizar la contraparte unsigned , uintptr_t .

Como se mencionó en la otra respuesta de chux , la comparación de punteros es otro aspecto importante.

Además, FWIW, según la norma C11 , §7.20.1.4,

Estos tipos son opcionales.


También hay una consideración semántica.

Se supone que un void* apunta a algo . A pesar de la practicidad moderna, un puntero no es una dirección de memoria. Bien, generalmente / probablemente / siempre (!) Tiene uno, pero no es un número. Es un puntero Se refiere a una cosa.

Un intptr_t no lo hace. Es un valor entero, que es seguro convertir a / desde un puntero para que pueda usarlo para API antiguas, empaquetándolo en un argumento de función pthread , cosas así.

Es por eso que puede hacer más cosas grandes y pequeñas en un intptr_t que en un void* , y por qué debería autodocumentarse utilizando el tipo adecuado para el trabajo.

En última instancia, casi todo podría ser un número entero (recuerde, ¡su computadora funciona con números!). Los punteros podrían haber sido enteros. Pero no lo son. Son punteros, porque están destinados a diferentes usos. Y, en teoría, podrían ser algo más que números.