我读了标准,但仍无法确定:
#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';
呢?
答案 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的调用是没有定义的行为。