2010-04-09 23 views

Respuesta

20

En general, no se puede. En algunos casos, si hay una garantía sobre lo que p señala, es posible que pueda ver los contenidos en y después de esa dirección para averiguarlo. En general, su función debe saber lo que se está transmitiendo, a menos que simplemente la transfiera.

Los argumentos de datos y funciones en C son solo un grupo de bits agrupados. A menos que use algunos de esos bits para decirle cuáles son los bits, no hay una manera consistente de identificarlo.

+6

Votando esto ... ya sabes porque te has asegurado de los tipos en el resto de tu programa. Si eso suena frágil es porque es frágil. Bienvenido a C. Utiliza un sistema menos frágil donde puedas. –

+0

Recuerdo algún código Motif (de todas las cosas) un tiempo atrás en el que obtendrías un puntero, y mirarías los primeros bytes después del puntero para determinar cuál era el tipo, y luego manejarías ese tipo apropiadamente. Que desastre. – WhirlWind

+0

No haré esto en la práctica. Solo tenía curiosidad de las formas en que esto se puede hacer. Además, una extensión GNU C proporciona el operador typeof() que (creo) podrá determinar el tipo de lo que se desreferencia (es decir, typeof (* p)), pero aún no lo he usado. – Yktula

5

Respuesta corta: no se puede.

En C no hay información de tiempo de ejecución a menos que la proporcione, pero mira a la familia printf(3) y ver lo fácil que es para disparar en el pie con la especificación de formato no coinciden y tipo de argumento real.

El sistema de tipos es tu amigo. Úselo.

5

Claro que sí, y es fácil también. Es C, haz lo que quieras, cómo lo quieras.

Haz un sistema de tipos. Ponga todo lo que pase en una estructura, haga que el primer byte o dos sea un número mágico para determinar qué contiene la estructura más allá del número mágico.

Realice algunas funciones para crear/obtener/establecer/destruir las "variables tipadas".

Realice algunas otras funciones para agregar y registrar nuevos tipos en el tiempo de ejecución.

Crea algunas define para que sea más fácil leer y encasillar las estructuras.

Antes de que te des cuenta, tendrás un buen sistema de tipo propietario que puedes usar para tus proyectos, y siempre hará EXACTAMENTE lo que quieras y necesites porque TÚ lo lograste.

Puede volverse loco y convertirlo en un objeto completo orientado como un sistema. O bien, sálvate el trabajo y utiliza el trabajo de todas las personas que ya se volvieron locos: http://en.wikipedia.org/wiki/GObject

+0

Entonces, ¿cómo funciona esto cuando la función que escribe se llama desde un código que no controla? – WhirlWind

+2

Si se está llamando a la función desde un código que no controla, entonces está haciendo la API/Biblioteca, por lo que debe documentar la interfaz y las funciones para crear/obtener/establecer/destruir las variables tipadas. Si por alguna razón el destinatario es el que tiene el control, y no quiere/se niega a usar su sistema personalizado 'tipado', entonces no tiene suerte. Tienes que dejar que ellos decidan cómo van a pasar tu información mecanografiada, y codificarla para eso. – Antebellum

1

Me enfrenté a un problema similar y tuve que escribir un conjunto de instrucciones para un proyecto de lenguaje de programación. Me encontré con este problema porque tenía una serie de punteros a funciones para que las funciones pudieran enumerarse y ejecutarse en un ciclo for (para cosas como ayuda en línea y sintaxis, etc.). Por ejemplo:

struct List_Str *(*InstructionSet[])(struct List_Str *ContextPrefix,struct List_Str *ContextSuffix)= 
{ 

    AAVF,Add,AddEmotions,AddEmoDebug,AddScope,... 

}; 

Ahora usted podría fácilmente hacer lo mismo con char * en lugar de struct List_Str * tipos, a continuación, convertir todos los datos en formato de cadena usando snprintf y atoi y atof y otras funciones de conversión. Si lo hace un:

man isalpha 

Esto muestra una gran cantidad de funciones en ctype.h que podrían darle ideas de cómo determinar qué tipo de datos se lleva a cabo dentro de las cuerdas.

Plegar todos los tipos en formato "fibroso" permite una tremenda flexibilidad y regularidad, pero convertir automágicamente los datos de las cadenas a enteros, flotantes, etc., es arduo pero fructífero una vez que las rutinas se librifican.

Si tiene la intención de almacenar datos binarios, no puede usar cadenas, ya que 0 caracteres pueden estar dentro de los datos binarios y esto confunde las funciones de strlen. Además, no tiene idea de la longitud de lo que ha sido malloc una vez que sale del alcance, por lo que se almacena la longitud de los datos sin referencia antes de que se recomienden los datos en los primeros bytes de char *.

Una última cosa, no recomendaría almacenar datos en el vacío *, es demasiado vago. Recomiendo usar char * ya que es un poco más específico, puede contener todo lo que void * puede y el compilador le avisará de antemano si algo parece sospechoso.

+2

Si usa 'char *' como un puntero de datos genérico, es muy fácil en mi humilde opinión quitar accidentalmente el puntero sin convertir primero al tipo adecuado. –

Cuestiones relacionadas