I want to sizeof of data types in for-cycle. I wrote function with macros that print sizeof of argument (argument is data type). I need to use struct with data-types-elements and indexing them. How can I realize it or how to work around this problem?
Code:
#define t_array = [ int, float ];
#define t_size(type) printf("%d", sizeof(type));
int main()
{
t_size(t_array[0]);
return 0;
}
>Solution :
It’s impossible to have an array of data types.
Instead you can use preprocessor to have an array of tokens.
#include <stdio.h>
#define ARRAY int, float
#define GET_1(_1) _1
#define GET_2(_1,...) GET_1(__VA_ARGS__)
#define GET_3(_1,...) GET_2(__VA_ARGS__)
#define GET_N2(_3,_2,_1,N,...) GET##N
#define GET_N(...) GET_N2(__VA_ARGS__,_3,_2,_1)
// GET idx argument from comma separated tokens
#define GET(array, idx) GET_N(array)(array)
int main() {
printf("%zu\n", sizeof(GET(ARRAY, 0)));
}
Or you can store the sizes (and other type-abstract) properties in array with elements for each type. (This is most importantly used with virtual functions that abstract operations on each type and results in nice non-spaghetti code, but calling a virtual function results in runtime overhead).
#include <stdio.h>
struct type_property {
size_t size;
};
#define TYPE_PROPERTY_INIT(type) { sizeof(type) }
struct type_property properties[] = {
TYPE_PROPERTY_INIT(int),
TYPE_PROPERTY_INIT(float),
};
int main() {
printf("%zu\n", properties[0].size);
}
Etc, there are other ways for writing type-abstract or templated code in C programming language that use these in a clever way. Like you can generate functions with preprocessor:
#include <stdio.h>
#define TYPESTUFF_DECL(SUFFIX, TYPE) \
size_t typestuff_size_##SUFFIX(void) { \
return sizeof(TYPE); \
}
TYPESTUFF_DECL(0, int)
TYPESTUFF_DECL(1, float)
int main() {
printf("%zu\n", typestuff_size_0());
}
Or you can have a whole file that is templated over tokens to generate those functions (see ex. STC for usage):
// typestuff.h
#ifndef TYPESTUFF_H_
#define TYPESTUFF_H_
#define TYPESTUFF_CONCAT(a, b) a##b
#define TYPESTUFF_CONCATX(a, b) TYPESTUFF_CONCAT(a, b)
#endif
static size_t TYPESTUFF_CONCATX(typestuff_size_, SUFFIX)(void) {
return sizeof(TYPE);
}
#undef SUFFIX
#undef TYPE
// main.c
#include <stdio.h>
#define SUFFIX 0
#define TYPE int
#include <typestuff.h>
#define SUFFIX 1
#define TYPE float
#include <typestuff.h>
int main() {
printf("%zu\n", typestuff_size_0());
}
Or you can enumerate each type and write big ugly very bad to maintain case statements, please don’t do it, because you’ll end up with this DLMS library:
#include <stdio.h>
#include <assert.h>
enum types {
TYPE_INT,
TYPE_FLOAT,
};
size_t types_sizeof(enum types idx) {
switch (idx) {
case TYPE_INT: return sizeof(int);
case TYPE_FLOAT: return sizeof(float);
};
assert(0);
}
int main() {
printf("%zu\n", sizeof(types_sizeof(0)));
}
Note that to print size_t as result from sizeof you should use %zu.