【发布时间】:2021-01-31 06:22:35
【问题描述】:
假设我有一个大数组,我正在执行以下操作:
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i)
printf("arr[%d]=%d\n", i, arr[i]);
当然,sizeof 的东西不应该每次都计算,所以应该是这样的:
size_t len = sizeof(arr)/sizeof(arr[0]);
for (int i = 0; i < len; ++i)
printf("arr[%d]=%d\n", i, arr[i]);
我的问题是,是否可以假设任何编译器都会自动进行上述优化,所以我使用哪种方法并不重要?或者我应该假设情况并非如此,第二种方法是唯一正确的方法。
【问题讨论】:
-
优化将取决于您使用的编译器。我肯定会采用第二种方法。
-
sizeof和strlen在这里是完全不同的动物。sizeof(type)或sizeof(obj)是一个编译时间常数,除了 VLA,所以sizeof(arr)/sizeof(arr[0])只是被编译器视为24/4和 constant folding 在任何理智的编译器上都会将其转换为常数6.但strlen是完全不同的情况。 -
@NateEldredge 我明白了,但是在上面是的,它也可能是 VLA。
-
即便如此,它不能在迭代之间改变,所以它应该是 hoisted 的循环。但在
for (i = 0; i < strlen(s); i++)的情况下,编译器不得不怀疑循环体是否会修改字符串s。如果它不能证明它没有,这可能很难,那么它必须在每次迭代时再次调用strlen。