I'm currently looking to calculate the total size of arguments passed into a function, in bytes. In theory, one can just write out sizeof(x)
for every argument. However, this is a tremendous waste of time if one wants to do this for a lot of functions. I'm trying to figure out the amount of space for the arguments so I can allocate the right amount of memory to store them all and store them (for a variety of functions, with mixed types).
I'm looking to make an expression that can determine the size of all arguments to a non-variadic function, regardless of their names and regardless of how many there are (within reason, I'm fine with supporting only about 64 arguments for now). It can be a function, a preprocessor macro, I'm agnostic to the implementation. I'd also be interested in handling variadic functions, but I'm pretty sure that is impossible because by the time you're into a variadic function you've lost all information about the data types.
At present, I've found three approaches that might be twisted to let me do this. The first one is based on the concepts from Laurent Deniau's arg counting. In theory, I can use a macro to generate the function header, and do some similar fancy footwork to take the number of args and dispatch to various macros that handle EACH individual case where there are N arguments. (See: Ugly). Basically, I'd just be aliasing all the function names using a macro and then using sizeof on each one of them. The problem is, I'd need to make a macro for EVERY length of arguments I want to represent. And I'd really not prefer to make 64 (or more) things to do one job.
The second approach is to try to follow the approach of Ben Klemer's 'better variadic' stuff. I wouldn't be using all of his approach, but I'd be trying to generate a struct that represents the arg signature of a function into a structure. I could then try to get the sizeof the structure elements (or even the structure itself, if all I cared about was a conservative estimate of the space). This has a few issues. First, it may only work on C99 compliant things (still checking on that). Second, it leads to the creation an additional structure for every function implemented. That's not entirely a problem, but it still has the issue that his approach to making a struct ends up with the same names as the function (so you still need to refer to the names to use them). I could probably work around that though.
The third approach that would be possible would be a recursive macro, though I'm not sure how happy that makes compilers. It's theoretically possible to recursively pop elements off of VA_ARGS by calling a macro in the form POPPER(arg, ...) POPPER(VA_ARGS) + sizeof(arg)
. Clearly, it would need a halting rule for when VA_ARG is empty (and something to make sure you don't get caught with a floating + sign), but you get the idea.
Any one of these things would allow me to do this:
- Good, flexible ways to unpack the VA_ARGS from a variadic macro. If there's any way to index it
- A good example of a recursive macro that could be relied upon to do this (as well as its limitations in max # of args, compiler compatibility, standards compliance, etc).
- A way to directly get the total size of all the args through a different type of function inspection. GCC seems to have some crazy functions for constructing function calls for call forwarding that might be applicable, but these are compiler-specific, barely documented, and do not appear to report the size of the block of memory they allocate. They also report back tons of irrelevant information.
sizeof()
never wastes any time since it gets always calculated by the compiler at compile time. It is not a function but merely a operator. – x4u