What does sizeof (int [1]) mean?

I am new to the Linux kernel. I read the ioctl.h file, there I came across the _IOC_TYPECHECK(t) macro, which looks like this:

 #define _IOC_TYPECHECK(t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC) 

Can you explain this code to me? In this code, what does sizeof(t[1]) mean?

+8
c macros sizeof linux-kernel
source share
2 answers

This is used to validate the third parameter on the _IOR / _IOW / _IOWR , which must be a type. It checks that this parameter is actually a type (not a variable or a number) and causes a compiler or linker error.

  • If t is a type, then t[1] is the type "array of 1 t ". This type has the same size as t , and therefore sizeof(t) == sizeof(t[1]) is true.

  • If t is a number, sizeof(t) will not compile.

  • If t is a simple (not an array) variable, then t[1] will cause a compiler error.

  • If t is an array variable, sizeof(t) == sizeof(t[1]) will be false and a linker error will be __invalid_size_argument_for_IOC (since __invalid_size_argument_for_IOC is undefined).

The expression sizeof(t) < (1 << _IOC_SIZEBITS) verifies that the size of type t does not exceed the maximum value for ioctl , and otherwise leads to the same linker error.

There are some other invalid cases that this macro will not catch - for example, when t is a pointer to a pointer.

+7
source share

This means that everyone else uses sizeof . It calculates the size of the expression.

In this particular case, I suspect that the check is intended to provide some property t (which should be a type name, not a variable), which I do not know from the context ... Perhaps this can be considered as a pointer (necessary for indexing the array) which excludes some types. The comment next to the macro says /* provoke compile error for invalid uses of size argument */ , which seems to support this theory.

Note that sizeof is an operator, not a function. Brackets are not needed, unless you want to directly calculate the type size, and then they are part of the expression (this is the expression for the expression). Therefore, for clarity, this can be written sizeof t == sizeof t[1] && ... or maybe (sizeof t == sizeof t[1]) .

This is a very good style to use, since it "blocks" the size calculated by the corresponding array, instead of repeating the type t . So, if the type was to change, the expression will automatically adapt and still correctly evaluate.

Many C programmers seem to for some reason prefer to have parentheses around the sizeof argument in all cases.

+3
source share

All Articles