Macro to both get (void*) address of item and length, for arrays and structs
I'm trying to design a macro to produce several related data structures related to things that need initialization. The code has to compile under both C and C++. The goal is to have something like:
MUNGE_THING(struct1); MUNGE_THING(array1);
turn into something equivalent to
munge_thing((void*)&struct1, sizeof(struct1)); munge_thing((void*)array1, sizeof(array1));
Is there any syntactic stuff I can surround the macro argument with so that it will handle both arrays and structure correctly both when taking the address and when getting the size? The most likely context will be in the constant declaration of a开发者_JS百科n initialization list.
If that isn't possible, and it's necessary to use separate macros for structures and arrays, what would be the best syntax to ensure that passing something incorrectly will yield a compile error rather than bogus code?
In "old" C, prepending an array address with "&" would yield a warning, but not prevent compilation. In C++, it seems to yield the address of a location which stores the address of the array.
The MUNGE_THING macros are going to be within another macro that will be invoked multiple times with different definitions of MUNGE_THING, so having separate macros for arrays and structs would be irksome. The best approach I can figure would be to give MUNGE_THING an extra argument for the "optional" ampersand, but that somehow seems ugly.
If the array is in fact an array (which seems to be required for the sizeof
to work), why don't you just use the simple macro:
#define MUNGE_THING( x ) munge_thing((void*)&(x), sizeof(x))
That should work both for arrays and structs:
int array[10];
assert( (void*)array == (void*)&array );
You have tagged the question as both C and C++, in C++ you can use templates and avoid the macros all together.
I'm not sure what problem you are having with &array1
. This C++ worked exactly as expected (all values the same)
int main(int argc, char* argv[])
{
int array1[10];
printf("%x %x\n", array1, &array1);
cout << array1 << " " << &array1 << endl;
void* ptr1 = array1;
void* ptr2 = &array1;
printf("%x %x\n", ptr1, ptr2);
cout << ptr1 << " " << ptr2 << endl;
return 0;
}
Okay, I see my confusion. In C++, the type of &array is not compatible with the type of the array, and as the linked discussion notes, (&array)+1 is not the same as (array+1), but casting the unsubscripted pointers does in fact yield the proper results. The distinctions between arrays and pointers in C are very confusing. Thanks for the assistance.
精彩评论