代码之家  ›  专栏  ›  技术社区  ›  Don McCaughey

何时使用限制,何时不使用

  •  22
  • Don McCaughey  · 技术社区  · 15 年前

    我对 restrict 但我希望澄清一些细节。我有一个函数,它从一个缓冲区中读取以空结尾的字符串,并在另一个缓冲区中写出一个URL编码的版本。函数具有此签名(当前没有 限制 ):

    char const *StringUrlEncode(char const *unencoded, 
                                char *encoded,
                                char *encodedEnd);
    

    unencoded 是以空结尾的源字符串。目标缓冲区由表示 encoded encodedEnd 在哪里 编码的 指向第一个 char 在缓冲区和 编码端 指向第一个字符 之后 缓冲区,即函数将写入 烧焦 到目前为止 不包括 指向的位置 编码端 --这是你的基本要求 begin / end 如果您熟悉C++ STL约定,则迭代器对。

    如果我添加 限制 对于此函数,应仅应用于前两个参数:

    char const *StringUrlEncode(char const *restrict unencoded, 
                                char *restrict encoded,
                                char *encodedEnd);
    

    或者,将它添加到所有三个参数中有什么好处我不理解吗?

    我可以看到,制作输入和输出缓冲区 限制 帮助编译器知道它们不重叠。但从最后一个参数开始, 编码端 ,仅用于标记输出缓冲区的结尾,我认为 限制 对这里的编译器没有任何帮助(尽管我认为它不会受到伤害,除了在函数声明中添加不必要的噪声之外)。

    3 回复  |  直到 12 年前
        1
  •  12
  •   Dan Olson    15 年前

    试试迈克·阿克顿的文章 here .限制是可怕的,因为不使用它的性能影响和不正确使用它的后果。

    在您的例子中,听起来您可以安全地将restrict应用于所有三个指针,因为没有一个别名是相同的内存区域。但是,在第三个指针上使用它对性能几乎没有好处。

        2
  •  7
  •   Crashworks    15 年前

    在这种情况下,是否 编码端 是否有限制;您已向编译器承诺没有任何别名 未编码的 编码的 所以读写不会互相干扰。

    在这种情况下,限制很重要的真正原因是没有它,编译器就无法知道 编码的 不会影响读取 未编码的 . 例如,如果

    encoded == unencoded+1
    

    然后每个人都写信给 编码的 会影响后续的每次读取 未编码的 ,因此编译器无法调度加载,直到写入完成。restrict向编译器保证两个指针不会影响同一内存,因此它可以提前安排足够远的加载,以避免管道阻塞。

        3
  •  4
  •   Matthew Flaschen    15 年前

    我认为你是对的,它不会伤害你。循环指针(称为p)在循环结束时将等于encodendend。但是在循环之后不需要访问任何东西(从p或encodendend),所以这不应该是一个问题。我也不认为它会有帮助,因为没有任何东西是写或从encodendend读取的,所以没有什么可以优化的。

    但我同意你的前两个限制应该真的有帮助。