Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 何时使用限制,何时不使用限制_C_Pointers_C99_Restrict Qualifier - Fatal编程技术网

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

C 何时使用限制,何时不使用限制,c,pointers,c99,restrict-qualifier,C,Pointers,C99,Restrict Qualifier,我对restrict有一个大致的了解,但我希望澄清一些细节。我有一个函数,它从一个缓冲区读取以null结尾的字符串,然后在另一个缓冲区中写出URL编码的版本。该函数具有此签名(当前没有restrict): unencoded是以null结尾的源字符串。目标缓冲区由encoded和encodedEnd表示,其中encoded指向缓冲区中的第一个char,而encodedEnd指向缓冲区后的第一个char,即函数将写代码< char >代码> s,但不包括由代码> >编码结束>代码>的位置。这是您的

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

unencoded
是以null结尾的源字符串。目标缓冲区由
encoded
encodedEnd
表示,其中
encoded
指向缓冲区中的第一个
char
,而
encodedEnd
指向缓冲区后的第一个char,即函数将写代码< char >代码> s,但不包括由代码> >编码结束>代码>的位置。这是您的基本代码<开始> <代码> />代码>结束>代码>迭代器对,如果您熟悉C++ STL约定。

如果我将
restrict
添加到此函数,它是否应仅应用于前两个参数:

char const *StringUrlEncode(char const *restrict unencoded, 
                            char *restrict encoded,
                            char *encodedEnd);
或者将它添加到所有三个参数中是否有一些我不理解的好处


我可以看出,使输入和输出缓冲区
restrict
有助于编译器知道它们不会重叠。但由于最后一个参数,
encodended
,仅用于标记输出缓冲区的结束,因此我认为
restrict
在这里对编译器没有任何帮助(尽管我认为这不会有什么坏处,除了在函数声明中添加不必要的噪声)

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

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

试试Mike Acton的文章()。限制是可怕的,因为不使用它会对性能产生影响,并且会导致错误使用它的后果


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

在这种特殊情况下,encodendd是否受到限制没有什么区别;您已向编译器承诺,没有人将未编码的编码的作为别名,因此读写操作不会相互干扰

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

encoded == unencoded+1

然后,对编码的的每次写入都会影响从未编码的进行的后续读取,因此编译器无法在写入完成之前安排加载。restrict向编译器保证这两个指针不会影响相同的内存,因此它可以提前安排足够多的加载,以避免管道暂停。

注意,取消引用encodedEnd是未定义的行为,因为encoded也是restrict-所以实际上,encodedEnd是否受限制根本不重要。我读过Mike的文章(现在两次)这是一个好的开始,但给我留下了一些问题:-)给出的链接不起作用。谷歌建议在(2009-09-06)上有一个更新版本,但这也带来了问题。缓存版本可以在谷歌上找到。
encoded == unencoded+1