How can I write my own sizeof operator? Any idea please?
Printable View
How can I write my own sizeof operator? Any idea please?
Why do you want to do this?
No I was just asked but couldn't answer.
Any idea please?
I may be wrong, but I believe that it is impossible in standard C.
I think the sizeof operator has a lot of support from the compiler and can operate at compile time so anything you build at runtime wouldn't have the same usage
>Why do you want to do this?
"Find the size of an object without using the sizeof operator" is not an uncommon trivia question.
>I may be wrong, but I believe that it is impossible in standard C.
Duplicating the exact semantics of sizeof would require writing your own preprocessor. But if you reduce the problem to getting the size of an existing object rather than either a type name or an existing object, it's pretty easy:
Accepting a type name in any convenient way is harder because ultimately you would want to declare a temporary object and use the above solution.Code:#define SIZEOF(x) ((char*)(&(x) + 1) - (char*)&(x))
>Okay so what does the above macro mean.
Subtracting two pointers results in the number of items[1] between those pointers. If you cast the two pointers to char*, subtraction then results in the number of bytes between the two pointers[2]. With that in mind, the macro creates two pointers from the object: one to the object itself and one to the "next" object[3]. Those two pointers are cast to char*, because we want the number of bytes between them and not the number of objects (we already know the number of objects is 1). Finally, the two pointers to char are subtracted to get the difference between the addresses in bytes.
[1] Where an item is an object of the pointed to type. So if p and q are pointers to int, p - q tells you how many objects of type int there are between those two addresses.
[2] The char type is guaranteed to be one byte.
[3] The "next" object doesn't really exist, but the address can still be calculated. Just don't dereference that pointer. ;)
I don't know - I think this does the trick (only managed to work this out after seeing your SIZEOF macro, though...):
Code:#include <stdio.h>
#define SIZEOF(X) \
({ \
__typeof__(X) x; \
((char *)(&x + 1) - (char *)&x); \
})
int main(void)
{
struct s {
int x;
float p;
int y;
};
printf("%d\n", SIZEOF(struct s));
return 0;
}
>I don't know - I think this does the trick
I'm sure it does...on your compiler. Keep in mind that my reply to laserlight was in reference to standard C. If you leave the realm of portability, anything is possible. The big problem with a sizeof macro in standard C is being able to create a temporary object and also use the macro as an expression (the paren wrapped compound statement you used is a compiler extension). If you change the semantics, it can be done easily:
But this solution may or may not be valid depending on the limitations of the question. Usually the question requires the macro to have as close to an equivalent syntax to the sizeof operator as possible.Code:#include <stdio.h>
#define SIZEOF_T(X,result) { \
X x; \
result = (unsigned long)((char *)(&x + 1) - (char *)&x); \
}
int main(void)
{
struct s {
int x;
float p;
int y;
};
unsigned long size;
SIZEOF_T(struct s, size);
printf("%lu\n", size);
return 0;
}
I didn't realise that. Fair enough - in that case, here's one that works for types and objects with no temporaries and (I think) is completely portable. By that, I mean it compiles on my machine with tcc and gcc -Wall -Wextra -Werror -g -std=c99 -pedantic-errors.
Code:#include <stdio.h>
#define SIZEOF(X) ((int)(&(*(__typeof__(X) *)0) + 1))
int main(void)
{
struct s {
int x;
float p;
int y;
} S;
printf("%d\n", SIZEOF(struct s));
printf("%d\n", SIZEOF(S));
return 0;
}
I don't think __typeof__ is part of C89 nor C99.
>Why not something like: [using NULL as a temporary]
Arithmetic on a null pointer isn't portable. Though to be fair, it'll probably work on the majority of systems.
Yeah, but it is a different question.Quote:
Originally Posted by Prelude
Indeed, I cannot find anything with "typeof" in the text of C99.Quote:
Originally Posted by Bayint Naung