如果标准符号为1,为什么要写`sizeof(char)`

Eim*_*tas 49 c coding-style

我正在做一些C编码,在阅读了一些C代码后,我注意到有类似的代码片段

char *foo = (char *)malloc(sizeof(char) * someDynamicAmount);
Run Code Online (Sandbox Code Playgroud)

所以我想问一下C-ish为char数组分配内存的方法是什么?sizeof(char)对任何标准更改使用并假设未来的代码更改或省略它并直接使用数字?

APr*_*mer 65

Cish的方式就越多

char* foo = malloc(someDynamicAmount * sizeof *foo);
Run Code Online (Sandbox Code Playgroud)

引用变量而不是类型,以便不需要类型.并且没有强制转换malloc的结果(这是C++ ish).

  • @James:我看到它的方式,您可以选择重复类型(可能会导致不同步并引入错误),或重复变量名称.除非您的变量影响另一个,否则更改变量的名称并且无法更新malloc参数会导致编译失败("foo not defined"),因此这是一种更安全的重复. (16认同)
  • "这是C++ ish" - 好吧,如果您在C++中使用`malloc`,则必须转换返回值.我怀疑它是一个被误导的C语言,也可能是之前的C++习语.我觉得很有趣的是C代码的CERT顾问说你应该总是转换malloc的返回值,另一个说你永远不应该这样做. (8认同)
  • 这是更好的,因为如果改变`foo`的类型,它仍然会malloc正确的数量.在memcpy中执行此操作尤为重要. (4认同)
  • @Steve,有目的地设计一个库,以便它可以用C语言和C++编译,这有时是正确的做法.认为使用C++编译器编译随机C代码将无需修改即可使用是一种错觉.但是,在没有过多关注64位平台上的可移植性的情况下,比在32位平台上开发代码工作更麻烦. (4认同)
  • @Steve Jessop:在C89之前,`*alloc`函数返回`char*`而不是`void*`,所以cast*是必需的.这就是为什么这种做法如此难以消除的部分原因; 年长的程序员可能仍然习惯于这样做,当然,任何看过他们的代码或他们写的书的人都会看到这种做法并复制它.一旦我意识到不再需要它,我花了一段时间才停止这样做. (3认同)
  • @Steve,我知道人们使用C++编译器来编译C库,以便在其他C++程序中更容易使用它们(有些平台仍然存在? - 转换C代码的异常问题). (2认同)

Red*_*edX 29

sizeof(char)愿意明确意图.如果有人决定他想让foo成为一个int他知道他需要做sizeof(int)的就是继续工作.

或省略并使用该号码

另外,使用幻数不是很好的编码习惯.

  • 即使编译器设置为发出所有可能的警告,`int*foo = malloc(sizeof(char)*some_quantity)`也会毫无怨言地编译,默默地创建一个bug. (2认同)

Ste*_*ows 25

恕我直言最佳做法是写sizeof(*foo).如果foo的类型发生变化且sizeof未得到纠正,那么你也会被覆盖.


Arm*_*yan 11

相比:

float*baz = malloc(sizeof(float) * someDynamicAmount);
int  *bar = malloc(sizeof(int)   * someDynamicAmount);
char *foo = malloc(sizeof(char)  * someDynamicAmount);
Run Code Online (Sandbox Code Playgroud)

VS:

float*baz = malloc(sizeof(float) * someDynamicAmount);
int  *bar = malloc(sizeof(int)   * someDynamicAmount);
char *foo = malloc(someDynamicAmount);
Run Code Online (Sandbox Code Playgroud)

我喜欢第一个版本.你喜欢第二个吗?

  • 因此,如果代码片段是列表的一部分,这些列表具有内在相关性,并且您已经水平对齐它们 - 那么相关的是,如果您稍后为"long long"添加一个,那么您很乐意将diff显示为3除了添加的行之外,行也发生了变化 - *然后*可以编写`sizeof(char)`; .p (5认同)
  • @Steve:这与名单无关.它只是因为你恰好保证它的大小,所以不会对char的一般模式进行例外处理. (5认同)
  • @Steve Jessop:拥有某种语言专家的程序员将训练他们的眼睛来发现该语言的潜在wtfs.因为几乎所有的malloc都必须有sizeof(),如果在略过代码时你看到malloc没有一个,那么你将不得不暂停并四处查看它的类型,现在你意识到你浪费了你的时间暂停,因为它结果成为一个角色.这种停顿可能会破坏您正在思考的内容,并可能累积起来.保持一致是有好处的. (5认同)
  • ......好吧,那就是我会写一些大小的东西.如果由于某种原因以AProgrammer的方式写它是不合适的,那就是`sizeof(char)`.在实践中,对于读缓冲区,我写了`char*foo = malloc(BUF_SIZE);`,在几乎通用的代码中我写了`char*foo = malloc(sizeof(*foo)*ARRAY_SIZE)`.我不会将我看到的噪声添加到我的代码中,以便将前者视为与后者相同的"一般模式"的一部分. (2认同)

Dav*_*e S 7

按照标准,你是正确的,乘法是不可靠的.也就是说,这看起来像是一个人变得一致的习惯.如果你总是使用sizeof(),不管类型,你永远不会忘记.

char *foo = (char *)malloc(sizeof(char) * someDynamicAmount);
int  *bar = (int  *)malloc(sizeof(int)  * someDynamicAmount);
Run Code Online (Sandbox Code Playgroud)


Joh*_*ode 7

常见的习语是

T *p = malloc(N * sizeof *p);
Run Code Online (Sandbox Code Playgroud)

要么

T *p;
...
p = malloc(N * sizeof *p);
Run Code Online (Sandbox Code Playgroud)

这样您就不必担心类型了.