【问题标题】:Output of using sizeof on a function [duplicate]在函数上使用 sizeof 的输出[重复]
【发布时间】:2011-08-08 20:37:09
【问题描述】:

为什么下面的代码给出:

#include<stdio.h>

int voo()
{
    printf ("Some Code");
    return 0;
}


int main() {
    printf ("%zu", sizeof voo);
    return 0;
}

以下输出:

1

【问题讨论】:

  • 因为所有的东西都必须有一个正的、非零的大小?

标签: c sizeof


【解决方案1】:

C 语言没有为函数定义sizeof。表达式 sizeof voo 违反了约束,需要任何符合 C 编译器的诊断。

gcc 在函数指针上实现指针算术作为扩展。为了支持这一点,gcc 任意假设函数的大小为 1,因此将例如 42 添加到函数地址将得到一个超出函数地址 42 个字节的地址。

他们对 void 做了同样的事情,所以 sizeof (void) 产生 1,并且允许在 void* 上进行指针运算。

如果您想编写可移植的代码,最好避免这两个特性。使用-ansi -pedantic-std=c99 -pedantic 获取此类警告。

【讨论】:

  • 投反对票的人能解释一下原因吗?
  • Keith,SO 有一些开车经过的反社会人士;不要指望他们的解释。我给了你 +1。
  • @Jim:谢谢!但实际上,我更担心有人可能有合理的批评并且没有费心分享它的可能性。 (我想知道在否决时发表评论的要求会有多好。也许是元的问题。)
  • @Keith 有人可能对您的帖子提出合理的批评,但无法想象有人有正当理由对其否决。我认为这个要求是个好主意,并且符合常见问题解答。
  • 我长期以来一直支持这样的要求(或者,他们可以对现有评论进行投票,大概是对他们同意的答案的批评)。
【解决方案2】:

The C99 Standard 说:

6.3.2.1/4

除非是 sizeof 运算符 54) 的操作数或一元 & 运算符,一个函数指示符 类型“函数返回类型”被转换为具有类型“指针”的表达式 函数返回类型''。

在 54) 脚注中,它说

因为没有发生这种转换,所以 sizeof 运算符的操作数仍然是函数指示符,违反了 6.5.3.4 中的约束。

6.5.3.4的相关段落是

sizeof 运算符不得应用于具有函数类型或 不完整的类型

从中我们可以得出结论,您的程序调用了Undefined Behaviour,并且无法对输出给出解释。

【讨论】:

  • 是的,程序调用了未定义的行为(假设它完全编译,它可能不会编译)。这并不意味着“无法对输出给出解释”。例如,请参阅我对输出的解释。 (语言标准没有对输出做出解释,这是事实,而且非常相关。)
  • 当然,如果您知道用于编译代码的编译器、其选项、操作系统和月相,您可以解释 UB 的输出 :) OP 刚刚提示他正在使用 C99 编译器,这排除了 Microsoft Visual Studio...
  • 我只需要知道编译器,这是我从程序的输出中推断出来的。
  • @Keith 你是对的。 UB 并不意味着不能给出任何解释,或者类似的东西,令人遗憾的是,许多人提出了这种愚蠢的说法。这意味着 C 标准没有限制符合标准的实现可以做什么。
  • @Jim:这可能不适合进行这种元讨论,但我自己倾向于讨论两者,同时明确答案的哪一部分与标准语言和这是特定于实现的。恕我直言,即使是编写不可移植代码的人也可以从确切了解它的不可移植性中受益。 (顺便说一句,有一个“语言律师”标签。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2013-07-16
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多