don*_*e26 3 c compiler-construction const compiler-optimization
现代编译器可以在看到代码时优化代码const.但是,我从未见过C标准库const用于非指针参数.例如memcmp()是这样的一个例子.它有2个const void *参数,但它的第三个参数是size_t.
为什么标准库(和其他库)以这种方式设计?为什么我没有看到const size_t或const int现代的代码?
C使用call-by-value.它没有帮助编译器将函数参数标记为const(注意,没有参数memcmp()是const.指针参数也可以声明const,你可以建议它们应该是:int memcmp(const void * const s1, const void * const s2, size_t const n);.但它们不是).
它无法帮助编译器标记函数参数的原因const是,从函数的角度来看,函数参数只是一个局部变量.只要该函数不采用其地址,编译器就很容易看到该变量永远不会被修改.
相比之下,作为原型()的一部分的const修饰符是其合同的一部分:它们表示该函数不会修改指向的数据.该修改它从未在参数中使用这种方式本身,因为如果函数修改它的参数调用者并不关心:他们只是副本(再次因为C使用调用-值).memcmp()const void *s1const
这些const意味着不同的事情。在
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
Run Code Online (Sandbox Code Playgroud)
const void * ptr1意味着memcmp将被视为ptr1指向常量数据并且不会修改它;同样对于const void * ptr2. 因此,调用者知道存储的值不会改变,并且可以相应地进行优化。在像这样的函数调用中
int result = memcmp(ptr1, ptr2, num);
Run Code Online (Sandbox Code Playgroud)
变量ptr1、ptr2、 和num被复制到函数中。 memcmp不承诺不进行调整;它只承诺不调整指针指向的内容。事实上,如果证明有效的话,它可能会增加/减少任何复制的变量,以便逐步遍历数组。如果它想承诺不改变其中任何一个,声明将是:
int memcmp ( const void *const ptr1, const void *const ptr2, const size_t num );
Run Code Online (Sandbox Code Playgroud)
对于简单的数据类型(如指针和整数),通过这种方式可以获得很少的(如果有的话)优化,并且该函数(和其他函数)的原始说明符显然没有理由阻止实现在偶然情况下修改变量。