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

Don*_*hey 23 c pointers c99 restrict-qualifier

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

char const *StringUrlEncode(char const *unencoded, 
                            char *encoded,
                            char *encodedEnd);
Run Code Online (Sandbox Code Playgroud)

unencoded是我的以null结尾的源字符串.目标缓冲区由encoded和表示encodedEnd,其中encoded指向char缓冲区encodedEnd中的第一个并指向缓冲区的第一个字符,即函数将写入char不包括指向的位置encodedEnd- 这是您的基本begin/ end迭代器如果您熟悉C++ STL约定,请配对.

如果我添加restrict到此函数,它应该只应用于前两个参数:

char const *StringUrlEncode(char const *restrict unencoded, 
                            char *restrict encoded,
                            char *encodedEnd);
Run Code Online (Sandbox Code Playgroud)

或者通过将它添加到所有三个参数中我是否有一些好处?

我可以看到制作输入和输出缓冲区restrict有助于编译器知道它们不重叠.但是由于最后一个参数,encodedEnd仅用于标记输出缓冲区的结尾,我认为这restrict对编译器没有任何帮助(虽然我认为它不会受到伤害,除了添加不必要的噪声到函数声明).

Dan*_*son 12

在这里试试Mike Acton的文章.由于不使用它的性能影响以及错误使用它的后果,限制是可怕的.

在你的情况下,听起来你可以安全地将限制应用于所有三个指针,因为没有别名相同的内存区域.但是,在第三个指针上使用它几乎没有性能优势.

  • 给出的链接无效。谷歌建议在 http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html(2009-09-06 验证)上有一个更新版本,但这也带来了问题。缓存版本可在 Google 上获得。 (3认同)

Cra*_*rks 7

在这种特殊情况下,encodeEnd是否受限制并没有区别; 你已经向编译器承诺没有人对未编码编码进行别名,因此读写操作不会相互干扰.

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

encoded == unencoded+1
Run Code Online (Sandbox Code Playgroud)

然后每次写入编码都会影响来自未编码的每个后续读取,因此编译器无法在写入完成之前调度负载.限制承诺编译器两个指针不会影响相同的内存,因此它可以提前调度负载以避免管道停顿.