【问题标题】:What does sizeof(int[1]) mean?sizeof(int[1]) 是什么意思?
【发布时间】:2013-02-18 10:34:11
【问题描述】:

我是 Linux 内核的新手。我正在阅读文件ioctl.h,在那里我遇到了一个宏 _IOC_TYPECHECK(t),看起来像这样:

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

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

【问题讨论】:

    标签: c macros linux-kernel sizeof


    【解决方案1】:

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

    • 如果t 是一个类型,那么t[1] 是类型“1 个t 的数组”。此类型与t 大小相同,因此sizeof(t) == sizeof(t[1]) 为真。

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

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

    • 如果t是数组变量,sizeof(t) == sizeof(t[1])为假,会导致链接器错误(因为__invalid_size_argument_for_IOC没有定义)。

    表达式sizeof(t) &lt; (1 &lt;&lt; _IOC_SIZEBITS) 检查t 类型的大小不超过ioctl 允许的最大值,否则会导致相同的链接器错误。

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

    【讨论】:

    • “如果t 是一个数组变量,sizeof(t) == sizeof(t[1]) 将是假的”真的总是真的吗?
    • @AndreasGrapentin:不适用于包含一个元素的数组,但是您可能会收到编译器警告,因为索引数组超出范围。
    【解决方案2】:

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

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

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

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

    出于某种原因,在所有情况下,许多 C 程序员似乎都更喜欢在 sizeof 的参数周围加上括号。

    【讨论】:

    • t 这里应该是一个类型,而不是一个变量。这是_IOR/_IOW/_IOWR 宏的第三个参数。
    • 我不知道sizeof 的参数是可选的,除了类型;或者在这种情况下他们在技术上是一个演员。为此 +1!
    • “然后它们是表达式的一部分”。我不确定我明白你在这里的意思。类型标识符(如int)不需要括号,也不是表达式,但sizeof(int) 中需要括号,因为这是语法规则......或者你得到了什么不同的东西?另外,这也不是演员表。
    • @unwind C中涉及sizeof的一元表达式有两条语法规则:“sizeofunary-expression”和“sizeof(类型名称 )"。 (int) 不是一个强制转换表达式(它根本不是一个表达式),它只是一个括号中的 type-name,比如你可以放在 sizeof 标记之后。
    • 由于t 是一种类型,因此您关于省略括号的答案的后半部分不正确(此处必须使用括号)。而且前半段基本都是“不知道”。
    猜你喜欢
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多