1

我阅读了标准,但仍不能确定:

#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';呢?

4

3 回答 3

2

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

在不同的主题上,您不需要像C 中的类型那样进行'm'转换。(int)'m''m'int

于 2014-12-27T02:24:01.883 回答
0

我的印象是您restrict错误地理解了修饰符的目的。这是函数调用者必须提供的保证,即该对象不能通过任何其他指针访问,也不会被使用这样的另一个指针意外修改。所以限定指针的使用不会restrict导致UB。

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

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

于 2014-12-27T10:31:56.070 回答
0

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

编译器如何知道 cp 是从 ap 派生的?它不必知道。首先,无论编译器是否知道,都不会改变行为已定义或未定义。规则不是“如果编译器知道......”,规则是“如果 cp 是从 ap 派生的”。

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

于 2014-12-27T02:23:00.067 回答