Actualmente estoy buscando calcular el tamaño total de los argumentos pasados a una función, en bytes. En teoría, uno solo puede escribir sizeof(x)
para cada argumento. Sin embargo, esta es una gran pérdida de tiempo si uno quiere hacer esto para muchas funciones. Estoy tratando de calcular la cantidad de espacio para los argumentos, así puedo asignar la cantidad correcta de memoria para almacenarlos y almacenarlos (para una variedad de funciones, con tipos mixtos).C Función que calcula el tamaño total de los argumentos
Estoy buscando hacer una expresión que pueda determinar el tamaño de todos los argumentos para una función no variadica, independientemente de sus nombres e independientemente de cuántos hay (dentro de lo razonable, estoy de acuerdo con el apoyo solo sobre 64 argumentos por ahora). Puede ser una función, una macro de preprocesador, soy agnóstico para la implementación. También me interesaría manejar funciones variadas, pero estoy bastante seguro de que es imposible porque para cuando estás en una función variadica has perdido toda la información sobre los tipos de datos.
En este momento, he encontrado tres enfoques que podrían ser retorcidos para permitirme hacer esto. El primero se basa en los conceptos de Laurent Deniau's arg counting. En teoría, puedo usar una macro para generar el encabezado de la función, y hacer un trabajo de pies de fantasía similar para tomar el número de argumentos y despachar a varias macros que manejan CADA caso individual donde hay N argumentos. (Ver: feo). Básicamente, me limitaría a aliasar todos los nombres de funciones usando una macro y luego usando sizeof en cada uno de ellos. El problema es que necesitaría hacer una macro para TODOS los argumentos que quiero representar. Y realmente no preferiría hacer 64 (o más) cosas para hacer un trabajo.
El segundo enfoque es tratar de seguir el enfoque de Ben Klemer's 'better variadic' stuff. No usaría todo su enfoque, pero estaría intentando generar una estructura que represente la firma arg de una función en una estructura. Podría tratar de obtener el tamaño de los elementos de la estructura (o incluso la estructura en sí, si todo lo que me importaba fuera una estimación conservadora del espacio). Esto tiene algunos problemas. En primer lugar, es posible que solo funcione en cosas que cumplen con C99 (aún lo estoy comprobando). En segundo lugar, conduce a la creación de una estructura adicional para cada función implementada. Eso no es del todo un problema, pero todavía tiene el problema de que su enfoque para hacer una estructura termina con los mismos nombres que la función (por lo que todavía necesita consultar los nombres para usarlos). Sin embargo, probablemente podría evitarlo.
El tercer enfoque que sería posible sería un macro recursivo, aunque no estoy seguro de lo feliz que eso hace a los compiladores. Es teóricamente posible extraer elementos de forma recurrente de VA_ARGS llamando a una macro en el formato POPPER(arg, ...) POPPER(VA_ARGS) + sizeof(arg)
. Claramente, necesitaría una regla de detención para cuando VA_ARG esté vacío (y algo para asegurarse de no quedar atrapado con un signo flotante +), pero se entiende la idea.
Cualquiera de estas cosas me permitiría hacer esto:
- buenas maneras y flexibles para desempaquetar los VA_ARGS desde una macro variadic. Si hay alguna manera de indexarlo
- Un buen ejemplo de macro recursiva en la que se puede confiar para hacer esto (así como sus limitaciones en max # de argumentos, compatibilidad del compilador, cumplimiento de estándares, etc.).
- Una forma de obtener directamente el tamaño total de todos los argumentos a través de un tipo diferente de inspección de función. GCC parece tener algunas funciones crazy para construir llamadas a funciones para el reenvío de llamadas que podrían ser aplicables, pero estas son específicas del compilador, apenas documentadas y no parecen informar el tamaño del bloque de memoria que asignan. También informan toneladas de información irrelevante.
'sizeof()' nunca pierde tiempo ya que siempre lo calcula el compilador en tiempo de compilación. No es una función sino simplemente un operador. – x4u
Aplaudo su investigación preparatoria, pero ¿tiene una pregunta específica y responsable? –
Se puede hacer de una manera más o menos hackish y/o dependiente del sistema/compilador, pero para darte una sugerencia decente sería bueno si pudieras responder a la pregunta: ¿Qué piensas hacer con esta información y cuándo lo haces? ¿necesito? (en tiempo de ejecución, tiempo de compilación o simplemente como una métrica de código fuente?) – x4u