编译期字面量除法:C语言循环内sizeof数组长度计算是否会运行时重复执行?
问题解答
第一个问题:是否会在运行时每次迭代执行除法?
不会,该除法运算会在编译阶段全部完成,运行时不存在任何相关计算。
原因如下:
sizeof是C语言的编译期运算符,对于非可变长度的固定数组(你示例中的static int array[10]就属于这类),sizeof的返回值属于整数常量表达式,编译阶段就会确定具体数值,不会生成任何运行时计算指令。- 示例中
sizeof(array) / sizeof(array[0])的整个表达式,编译时就会被直接替换为对应常量(32位int环境下值为10),和直接在循环条件中写i < 10完全等价,循环运行时仅会执行整型比较操作,不存在除法运算。 - 该行为和编译优化等级无关,哪怕关闭所有优化(O0等级),也不会把这部分计算留到运行时。
第二个问题:是否需要调整为提取size变量的写法?
不需要为了性能做这个调整,两种写法的运行效率完全一致。
- 调整后的代码中,
static const int size的初始化值同样是编译期常量,编译后和原写法生成的汇编指令几乎没有差异,不会带来任何性能提升。 - 如果你是为了提高代码可读性,给数组长度起一个语义清晰的变量名,这种调整是非常推荐的,只是出发点不需要是“避免运行时除法”。
例外情况:只有当你使用C99引入的可变长度数组(VLA,即长度由运行时变量决定的数组)时,
sizeof才需要在运行时计算结果。即便在这种场景下,现代编译器大多也能识别到数组长度在循环周期内不会变化,自动优化为仅计算一次,不需要开发者手动提取变量。如果是极端追求执行确定性的场景,手动提取变量也没有问题。
内容的提问来源于stack exchange,提问作者Łukasz Przeniosło
相关产品推荐
相关产品推荐

