我可以在此功能中使用限制限定符吗?

时间:2014-12-27 02:16:05

标签: c c99 undefined-behavior c11 restrict-qualifier

我读了标准,但仍无法确定:

#include <stdio.h>
#include <string.h>

void repl(char *restrict ap){
    char *cp=strchr(ap,(int)'m');
    *cp='M';
}

int main(){
    char arr[] = "example";
    repl(arr);
    puts(arr);
    return 0;
}

在函数repl中,我使用strchr来获取另一个用于修改对象的指针。我希望结果是第一个m替换为M的字符串。

但这可能是未定义的行为吗?

如果是,那么使用ap[cp-ap]='M';代替*cp='M';呢?

3 个答案:

答案 0 :(得分:2)

别名规则允许通过自己的类型或字符类型(包括其签名/无符号变体)访问任何变量。这意味着*cp='M';是指定的行为,不需要任何特殊的预防措施,因为*cp是字符类型。

对于另一个主题,您不需要在'm'中投放(int)'m'因为'm'已在C中已为int类型。

答案 1 :(得分:0)

它不是未定义的行为,因为指针cp是从指针变量ap派生的。

编译器如何知道cp是从ap派生的?它不必知道。首先,编译器是否知道并不会改变行为是定义的还是未定义的。规则不是&#34;如果编译器知道......&#34;,则规则是&#34;如果cp是从ap&#34;得到的。

只要编译器无法证明cp不是从ap派生的,它就必须提供与您没有使用restrict关键字完全相同的语义。

答案 2 :(得分:0)

我的印象是,restrict修饰符的目的是错误的。这是函数调用者必须提供的保证,即对象不能通过任何其他指针访问,并且不会通过使用这样的另一个指针意外修改。因此restrict限定指针的用法不会导致UB。

此外,在您的情况下,您将这样的指针传递给函数。之后,编译器不能再假设指针不是别名,例如全局变量或函数返回的指针。 (它实际上是这样做的)

举个例子,它不是具有UB的函数memcpy。但是如果两个指针指向重叠的对象,那么你对memcpy的调用是没有定义的行为。