Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the easiest way to find the sizeof a type without compiling and executing code?

Tags:

c

bash

gcc

sizeof

I wrote a bash script to determine the size of gcc's datatypes (e.g. ./sizeof int double outputs the respective sizes of int and double) by wrapping each of its arguments in the following P() macro and then compiling and running the code.

#define P(x) printf("sizeof(" #x ") = %u\n", (unsigned int)sizeof(x))

The problem is that this is relative slow (it takes a whole second!), especially the linking step (since compiling with -c or -S takes virtually no time, and so does running the outputted binary). One second is not really that slow by itself, but if I were to use this script in other scripts, it would add up.

Is there a faster, less roundabout way to find out what sizes gcc uses for datatypes?

like image 706
Matt Avatar asked Dec 12 '22 01:12

Matt


2 Answers

You can achieve the functionality for standard types using the GCC's preprocessor only. For standard types there are predefined macros:

__SIZEOF_INT__
__SIZEOF_LONG__
__SIZEOF_LONG_LONG__
__SIZEOF_SHORT__
__SIZEOF_POINTER__
__SIZEOF_FLOAT__
__SIZEOF_DOUBLE__
__SIZEOF_LONG_DOUBLE__
__SIZEOF_SIZE_T__
__SIZEOF_WCHAR_T__
__SIZEOF_WINT_T__
__SIZEOF_PTRDIFF_T__

So, by using code like the following:

#define TYPE_TO_CHECK __SIZEOF_INT__
#define VAL_TO_STRING(x) #x
#define V_TO_S(x) VAL_TO_STRING(x)
#pragma message V_TO_S(TYPE_TO_CHECK)
#error "terminate"

you will be able to get the value of __SIZEOF_INT__ from the preprocessor itself without even starting the compilation. In your script you can define the TYPE_TO_CHECK (with -D) to whatever you need and pass it to gcc. Of course you will get some junk output, but I believe you can deal with that.

like image 126
Eugene Sh. Avatar answered Jan 18 '23 15:01

Eugene Sh.


You can use the 'negative array size' trick that autoconf (see: AC_COMPUTE_INT) uses. That way, you don't need to link or execute code. Therefore, it also works when cross compiling. e.g.,

int n[1 - 2 * !(sizeof(double) == 8)];

fails to compile if: sizeof(double) != 8

The downside is, you might have to pass -DCHECK_SIZE=8 or something similar in the command line, since it might take more than one pass to detect an unusual value. So, I'm not sure if this will be any faster in general - but you might be able to take advantage of it.

Edit: If you are using gcc exclusively, I think @wintermute's comment is probably the best solution.

like image 43
Brett Hale Avatar answered Jan 18 '23 17:01

Brett Hale