25

最近看到有人赞扬另一个用户使用 sizeof var 而不是 sizeof(type)。我一直认为这只是一种风格选择。有什么显着差异吗?例如,带有 f 和 ff 的行被认为比带有 g 和 gg 的行更好:

 typedef struct _foo {} foo;

 foo *f = malloc(count * sizeof f);
 foo *g = malloc(sizeof(foo) * count);

 foo **ff = malloc(count * sizeof *ff);
 foo **gg = malloc(sizeof(foo*) * count);

在我看来,第一组只是风格问题。但是在第二对行中,额外的第二个 * 很容易被混淆为乘法。

4

7 回答 7

51

如果变量的类型改变了,如果变量是参数而不是类型,则不需要改变 sizeof。

关于@icepack 的评论:类型与变量名称更改的可能性或可​​能性不是问题。想象一下变量名被用作 sizeof 的参数,然后再更改。在最好的情况下,重构重命名操作会更改所有出现的事件并且不会引入错误。在最坏的情况下,一个 sizeof 的实例会丢失,编译器会抱怨并修复它。如果类型改变了,你就完成了,在 sizeof 语句中没有错误的可能性。

现在想象类型是 sizeof 的参数。如果变量的类型发生了变化,除了检查之外没有其他方法可以找到与该变量相关的所有 sizeof。您可以搜索,但您将获得相同类型的 sizeof 的所有不相关使用的命中。如果遗漏了一个,由于大小不匹配,您将遇到运行时问题,这要查找起来要麻烦得多。

于 2008-12-17T00:17:13.787 回答
7

除了史蒂夫所说的,让我补充一点, sizeof 不评估它的操作数。所以你可以自由地做任何事情。您不仅可以使用尚未初始化的变量,还可以取消引用空指针、调用未定义但仅声明的函数以及执行任何其他类型的操作。我鼓励你总是使用表达式版本,因为史蒂夫解释得很清楚。

还要考虑到有时类型名真的很长而且不可读,想想指向函数的指针(尤其是在 C++ 中)。而不是写sizeof(my_long_type<weird, stuff>)你只是做sizeof t

于 2008-12-17T00:59:25.293 回答
4

您可能会发现这些之间几乎没有区别:

foo **ff = malloc(count * sizeof *ff);
foo **gg = malloc(sizeof(foo*) * count);

..但是如果分配不在声明附近怎么办?如果我遇到这样的一行:

ff = realloc(ff, count * sizeof *ff);

那么我有理由相信这条线是正确的,甚至不记得ff. 但是,如果我看到这个:

ff = realloc(ff, count * sizeof(foo *));

那么我可能会有些怀疑,需要查一下类型ff才能让我放心。

于 2009-12-22T05:21:56.133 回答
3

f 和 ff 行肯定比 g 和 gg 差。sizeof f是指针大小,因为 f 是一个点。为了使它们等效,您必须编写sizeof *f(或者,为了更好的易读性,sizeof(*f))。

于 2008-12-17T00:25:45.097 回答
2

我倾向于sizeof(type)在内存分配中使用,但sizeof(variable)在使用局部或全局变量时总是如此。尽管如此,始终使用变量名的建议是有智慧的。

我还进行了长时间的讨论(有时相当活跃,并且持续了几天——我们最终同意在这个问题上存在分歧)关于是否可以使用sizeof(variable)或是否必须使用sizeof variable;也就是说,括号是否将参数括起来是否重要sizeof。我从来没有遇到过sizeof(variable)sizeof. 我的同事同样坚持括号不能与变量一起使用。不知何故,带括号和不带括号的符号之间存在/曾经是有价值的区别。我没有被说服——我不希望被说服。

在完全不同的策略上,关于以下几点sizeof

  • 如果您使用 C99 和 VLA - 可变长度数组 - 那么sizeof(vla)它不是编译时常量。谨防!
  • C 预处理器不明白sizeof哪个是麻烦但合乎逻辑。
于 2008-12-19T07:17:27.883 回答
0

取变量的大小可能会产生意想不到的结果。当变量是数组时, sizeof(array) 将返回数组的大小,而不是单个元素的大小或指针的大小。获取指针的大小将返回指针的大小。但是由于数组在传递时通常表示为指针,所以事情会变得混乱。

于 2008-12-17T03:37:24.007 回答
0

业务逻辑定义您的选择。

  1. 如果您的代码引用了一个特定的变量并且没有这个变量,那么您的代码就没有意义 - 选择sizeof(var)

  2. 如果您的代码处理一组具有特定类型的变量 - 选择sizeof(type)。通常,如果您有一个typedef定义许多变量的变量,您需要根据它们的类型(例如序列化)以不同的方式处理这些变量。您可能不知道这些变量中的哪些将保留在未来的代码版本中,因此选择类型作为参数在逻辑上是正确的。即使更改此类typedef也不会影响您的sizeof线路。

于 2014-05-20T11:09:58.280 回答