2013-02-18 140 views
8

我是Linux内核的新手。我读文件ioctl.h,那里我遇到了一个宏观 _IOC_TYPECHECK(t),它看起来像这样:sizeof(int [1])是什么意思?

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

你能解释一下我这个代码?在此代码中,sizeof(t[1])是什么意思?

回答

7

这是用来检查第三个参数的有效性的_IOR/_IOW/_IOWR宏,它应该是一个类型。它检查该参数实际上是一个类型(而不是一个变量或一个数字),否则会导致编译器或链接器错误。

  • 如果t是一种类型的,那么t[1]是类型 “的1 t数组”。此类型的尺寸与t相同,因此sizeof(t) == sizeof(t[1])为true。

  • 如果t是一个数字,则sizeof(t)将无法​​编译。

  • 如果t是一个简单的(非数组)变量,那么t[1]将导致编译器错误。

  • 如果t是数组变量,sizeof(t) == sizeof(t[1])将为false,并且会导致链接器错误(因为__invalid_size_argument_for_IOC未定义)。

表达sizeof(t) < (1 << _IOC_SIZEBITS)检查该类型t的大小不超过最大允许的ioctl,并且使相同的接头错误否则。

仍然有一些无效的情况下不会被这个宏捕获 - 例如,当t是一个指针指针。

+0

“如果't'是一个数组变量,'sizeof(t)== sizeof(t [1])'将是错误的”是否真的是真的? – 2013-02-18 11:04:53

+0

@AndreasGrapentin:不适用于一个元素的数组,但是可能会出现编译器警告,以便将数组索引到界外。 – interjay 2013-02-18 11:46:18

3

这意味着与sizeof的所有其他用途相同。它计算表达式的大小。

在这种特殊情况下,我怀疑检查旨在确保t某些属性(这应该是一个类型的名称,而不是一个变量),我不从上下文知道......也许,这是可能的把它作为一个指针(数组索引所需)来排除某些类型。宏观旁边的评论说/* provoke compile error for invalid uses of size argument */似乎支持这一理论。

请注意,sizeof是一个运算符,而不是一个函数。括号不需要,除非你想直接计算一个类型的大小,然后它们是表达式的一部分(这是一个强制转换表达式)。所以为了清楚起见,可以将其写为sizeof t == sizeof t[1] && ...,或者可以是(sizeof t == sizeof t[1])

这是一个非常好用的样式,因为它将计算的大小“锁”到适当的数组,而不是重复t的类型。所以,如果类型改变了,表达式会自动适应并且仍然计算正确的东西。

许多C程序员似乎更喜欢在所有情况下围绕参数sizeof引用括号,出于某种原因。

+1

这里't'应该是一个类型,而不是一个变量。这是[_IOR]的第三个参数(http://h30097.www3.hp.com/docs/dev_doc/DOCUMENTATION/HTML/DDK_R2/DOCS/HTML/MAN/MAN9/0028___R.HTM)/ _IOW/_IOWR宏。 – interjay 2013-02-18 10:41:56

+0

我不知道'sizeof'的参数是可选的,除了一个类型;或者他们在技术上是在这种情况下演员。 +1就是这样! – Chowlett 2013-02-18 10:44:39

+1

“,然后他们是表达的一部分”。我不确定我明白你的意思。类型标识符(比如'int')不需要有括号,也不是表达式,但是在sizeof(int)中需要括号,因为这是语法规则......或者你得到的是不同的东西?此外,这也不是演员。 – 2013-02-18 10:46:11