【问题标题】:Compiler Optimization: const on non-pointer function arguments in C编译器优化:C 中非指针函数参数的 const
【发布时间】:2012-10-06 16:39:03
【问题描述】:

现代编译器可以在看到const 时优化代码。 但是,我从未见过 C 标准库将 const 用作其非指针参数。 例如,memcmp() 就是一个例子。它有 2 个const void * 参数,但它的第三个参数是size_t

为什么标准库(和其他库)是这样设计的?为什么我在现代代码中看不到 const size_tconst int

【问题讨论】:

    标签: c compiler-construction constants compiler-optimization


    【解决方案1】:

    C 使用按值调用。将函数参数标记为const 对编译器没有一点帮助(请注意,memcmp() 的所有参数都不是const。指针参数也可以声明为const,您可以建议他们应该是:int memcmp(const void * const s1, const void * const s2, size_t const n);。但他们不是)。

    标记函数参数const 对编译器没有帮助的原因是,从函数的角度来看,函数参数只是一个局部变量。只要函数不取其地址,编译器就很容易看出该变量从未被修改过。

    相比之下,const 修饰符是 memcmp() 原型 (const void *s1) 的一部分 是其合约的一部分:它们表示该函数不会修改指向的数据。 const 修饰符永远不会以这种方式用于参数本身,因为调用者不关心函数是否修改其参数:它们只是副本(再次因为 C 使用按值调用)。

    【讨论】:

    • 我的 Linux 手册页说 memcmp() 确实有 const 指针。
    • @dongle26 上面写着const void *,对吧?那是“指向 const 的指针”。指针不是 const。
    【解决方案2】:

    那些consts 意味着不同的东西。在

    int memcmp ( const void * ptr1, const void * ptr2, size_t num );
    

    const void * ptr1 表示memcmp 会将ptr1 视为指向常量数据,不会对其进行修改; const void * ptr2 也是如此。因此,调用者知道存储的值不会改变,可以进行相应的优化。在像

    这样的函数调用中
    int result = memcmp(ptr1, ptr2, num);
    

    变量ptr1ptr2num复制到函数中。 memcmp 不承诺不调整它们;它只承诺不调整指针指向的内容。实际上,如果证明有效,它可能会增加/减少任何复制的变量,以便逐步遍历数组。如果它想承诺不更改其中任何一个,则声明将是:

    int memcmp ( const void *const ptr1, const void *const ptr2, const size_t num );
    

    对于简单的数据类型(如指针和整数),通过这种方式可以获得很少(如果有的话)优化,并且这个函数(和其他函数)的原始说明符显然没有理由阻止实现修改偶然的情况。

    【讨论】:

      【解决方案3】:

      主要原因是库的一致性。将 size_t 参数更改为 const size_t 将需要修改要重写的大小的库。并非库的所有实现都需要使用相同的算法。这是现有库函数没有被适配的主要原因。

      新的库函数通常是有目的地使用非const 参数创建的,因此某些依赖于机器的实现可以使用可修改的参数。

      例如,memcmp 的英特尔 C++ 编译器版本实际上在执行期间倒计时 length 参数。其他一些实现可能不会这样做。

      【讨论】:

      • 不,你的回答没有多大意义。将函数的值参数设置为const 对你没有任何好处。
      • 确实如此。如果编译器决定内联函数,则不会复制 const 参数。
      • 如果现代编译器内联函数,它会进行常量传播,无论参数是否为const-qualified。 const 参数对函数定义 的唯一影响是您不能在函数内部更改它。对于声明,它没有任何区别。
      猜你喜欢
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多