代码之家  ›  专栏  ›  技术社区  ›  jmucchiello

带有类型或变量的“c”sizeof

  •  21
  • jmucchiello  · 技术社区  · 17 年前

    最近有人赞扬另一个用户使用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);
    

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

    7 回复  |  直到 12 年前
        1
  •  45
  •   Steve Fallows    13 年前

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

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

    现在假设类型是sizeof的参数。如果变量的类型发生了变化,除了检查之外,没有其他方法可以找到与该变量相关的所有sizeof。您可以搜索,但您将获得相同类型sizeof所有不相关用途的点击率。如果错过了一个,您将遇到一个运行时问题,因为大小不匹配,这是更困难的发现。

        2
  •  6
  •   Johannes Schaub - litb    17 年前

    除了史蒂夫所说的,让我补充一下sizeof不计算它的操作数。所以你可以在里面做任何事。不仅可以使用尚未初始化的变量,还可以取消对空指针的引用,调用未定义但只声明的函数,并执行任何其他类型的操作。我鼓励你总是使用表情版本,因为史蒂夫解释得很清楚。

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

        3
  •  4
  •   caf    16 年前

    你可能会发现这两者之间没有什么区别:

    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 让我的心平静下来。

        4
  •  3
  •   Martin v. Löwis    17 年前

    F和FF线肯定比G和GG线差。 sizeof f 是指针大小,因为f是一个点。为了使它们等价,你必须写 sizeof *f (或者,为了更好的易读性, sizeof(*f) )

        5
  •  2
  •   Jonathan Leffler    17 年前

    我倾向于使用 sizeof(type) 内存分配,但总是 sizeof(variable) 使用局部或全局变量时。然而,建议中始终使用变量名是明智的。

    我也进行了长时间的讨论(有时相当活跃,持续了几天——我们最终同意在这个问题上有所不同),讨论是否可以使用它。 sizeof(变量) 或者是否必须 sizeof variable 也就是说,括号是否将参数括起来 sizeof . 我从来没有遇到过一个编译器 sizeof(变量) ,所以我选择一致性,总是使用括号 西泽 . 我的同事同样坚定地认为括号不能与变量一起使用;不知何故,括号和不括号之间存在着一个有价值的区别。我没有被说服——我不希望被说服。

    在一个完全不同的策略上,关于 西泽 :

    • 如果你使用的是C99和VLA——可变长度阵列——那么 sizeof(vla) 不是编译时常量。当心!
    • C预处理器不理解 西泽 这很讨厌,但合乎逻辑。
        6
  •  0
  •   SoapBox    17 年前

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

        7
  •  0
  •   Riga    12 年前

    业务逻辑定义了您的选择。

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

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