Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C sizeof(长)与sizeof(*lp)_C_Compiler Construction - Fatal编程技术网

C sizeof(长)与sizeof(*lp)

C sizeof(长)与sizeof(*lp),c,compiler-construction,C,Compiler Construction,一段经常执行的代码具有以下计算: long *lp char *ep, *cp ... tlen = (ep - cp) / sizeof (*lp); 将此更改为: long *lp char *ep, *cp ... tlen = (ep - cp) / sizeof (long); 由于的sizeof是在编译时计算的,或者现代编译器已经在编译时处理了,因此会导致更高的效率。gcc做什么 sizeof总是在编译时计算的,所以没有区别。sizeof总是在编译时计算的,所以没有区别。size

一段经常执行的代码具有以下计算:

long *lp
char *ep, *cp
...
tlen = (ep - cp) / sizeof (*lp);
将此更改为:

long *lp
char *ep, *cp
...
tlen = (ep - cp) / sizeof (long);
由于的sizeof是在编译时计算的,或者现代编译器已经在编译时处理了,因此会导致更高的效率。gcc做什么

sizeof总是在编译时计算的,所以没有区别。

sizeof总是在编译时计算的,所以没有区别。

sizeof操作符总是编译时计算的构造0,所以没有区别

碎片

 tlen = (ep - cp) / sizeof (*lp);
因此将被转化成一种与

 tlen = (ep - cp) / 4;
假设sizeoflong==4 1.,应用优化后,下一个转换可能是

 tlen = (ep - cp) >> 2;
当然,还会有更多的优化;这只是它作为编译时构造0的一个可能结果的演示

我总是更喜欢sizeof_var-name_uuu而不是sizeof_typename_uuu,因为它更通用,并且在更改变量类型时不需要手动调整,从数组更改为指针时除外

0:可变长度数组除外

1:大小因平台而异

sizeof运算符始终是编译时计算的构造0,因此没有区别

碎片

 tlen = (ep - cp) / sizeof (*lp);
因此将被转化成一种与

 tlen = (ep - cp) / 4;
假设sizeoflong==4 1.,应用优化后,下一个转换可能是

 tlen = (ep - cp) >> 2;
当然,还会有更多的优化;这只是它作为编译时构造0的一个可能结果的演示

我总是更喜欢sizeof_var-name_uuu而不是sizeof_typename_uuu,因为它更通用,并且在更改变量类型时不需要手动调整,从数组更改为指针时除外

0:可变长度数组除外


1:大小因平台而异

您可以通过书写完全省去除法

tlen = ((long*)ep - (long*)cp);
不过,我不确定这项措施的实施是否会更有效率。我的小实验没有结果。测试


编辑:如注释中所述,只有指针实际指向long或适合容纳long的内存位置时,它才起作用。但是如果它们没有出现在原始代码中,那么原始结果也就没有意义了,所以我认为它们是有意义的。

您可以通过编写

tlen = ((long*)ep - (long*)cp);
不过,我不确定这项措施的实施是否会更有效率。我的小实验没有结果。测试


编辑:如注释中所述,只有指针实际指向long或适合容纳long的内存位置时,它才起作用。但是如果它们没有出现在原始代码中,那么原始结果也没有意义,因此我认为它们是有意义的。

不会导致性能差异,但会导致行为差异,具体取决于平台。例如:在Win x64上,SizeOfflong将为4,但sizeof*lp为8

不会导致性能差异,但会导致行为差异,具体取决于平台。例如:在Win x64上,sizeoflong将是4,但sizeof*lp是8

sizeof总是在可变长度数组之外,而可变长度数组在编译时常量的其他方面是有问题的。如果给它一个表达式,它会在编译时计算出该表达式类型的大小。sizeof总是不包括可变长度数组,这在编译时常量的其他方面是有问题的。如果给它一个表达式,它会在编译时计算该表达式类型的大小。不总是这样,因为C99有一些VLA在运行时大小不同。不总是这样,因为C99有一些VLA在运行时大小不同。如果ep和cp没有合适的长型对齐方式,则强制转换会调用未定义的行为。@R。。你说得对,我没想过。但是,如果指针没有对齐,OP的原始公式也会受到严重影响。@MrLister不,它没有对齐。很有可能代码没有意义,但就C语言而言,结果是定义良好的。是的,但我是在假设原始代码1确实有意义的情况下工作的,而2实际上按照预期工作的。这只有在指针的值对齐的情况下才能起作用。只要差异对齐,即使两个值没有单独对齐,原始代码也会避免有损除法。即使除法有损,它也不会调用UB。如果ep和cp对long类型没有合适的对齐方式,则强制转换会调用未定义的行为。@R。。你说得对,我没想过。但是,如果指针没有对齐,OP的原始公式也会受到严重影响。@MrLister不,它没有对齐。很有可能代码没有意义,但就C语言而言,结果是定义良好的。是的,但我是在假设原始代码1确实有意义的情况下工作的,而2实际上按照预期工作的。那可能
只有指针的值对齐时才有效。只要差异对齐,原始代码就避免有损除法,即使两个值没有单独对齐-即使除法有损,它也不会调用UB。