简体   繁体   中英

What does sizeof(int[1]) mean?

I am new to the Linux kernel. I am reading the file ioctl.h , there I encountered a macro _IOC_TYPECHECK(t) , 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 me this code? In this code, what does sizeof(t[1]) mean?

This is used to check the validity of the third parameter to the _IOR / _IOW / _IOWR macros, which is supposed to be a type. It checks that the parameter is actually a type (and not a variable or a number), and causes a compiler or linker error otherwise.

  • If t is a type, then t[1] is the type "an 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 fail to compile.

  • If t is a simple (non-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 caused (because __invalid_size_argument_for_IOC is not defined).

The expression sizeof(t) < (1 << _IOC_SIZEBITS) checks that the size of the type t does not exceed the maximum allowed for ioctl , and causes the same linker error otherwise.

There are still some invalid cases which will not be caught by this macro - for example, when t is a pointer to a pointer.

It means the same as all other uses of sizeof . It computes the size of the expression.

In this particular case, I suspect that the check is intended to ensure some property of t (which should be a type name, not a variable) which I don't know from the context ... Perhaps that it's possible to treat it as a pointer (needed for the array indexing) which would rule out 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. The parenthesis are not needed, except when you want to compute the size of a type directly, and then they're part of the expression (it's a cast expression). So this could be written sizeof t == sizeof t[1] && ... , or maybe (sizeof t == sizeof t[1]) for clarity.

This is a very good style to use, since it "locks" the size being computed to the proper array, instead of repeating the type of t . So, if the type were to change, the expression would automatically adapt and still compute the right thing.

Many C programmers seem to prefer having parenthesis around the argument to sizeof in all cases, for some reason.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM