Dor*_*son 6 c restrict-qualifier
我正在尝试对代码进行一些优化,但很难弄清楚“限制”在这种情况下是否有用或者是否会导致问题。
我有一个传递两个字符串 (char*) 和一个 int (int*) 的函数。
第二个字符串被复制到第一个字符串之后的内存中,位于 int 指示的位置。如果这会超出第一个字符串的内存分配,则必须在执行此操作之前为第一个字符串重新分配内存。使用新分配创建一个新指针,然后将原始第一个字符串指针设置为等于它。
char* concatFunc (char* restrict first_string, char* const restrict second_string, int* const restrict offset) {
size_t block = 200000;
size_t len = strlen(second_string);
char* result = first_string;
if(*offset+len+1>block){
result = realloc(result,2*block);
}
memcpy(result+*offset,second_string,len+1);
*offset+=len;
return result;
}
Run Code Online (Sandbox Code Playgroud)
上述函数被其他也使用限制关键字的函数重复调用。
char* addStatement(char* restrict string_being_built, ..., int* const restrict offset){
char new_statement[30] = "example additional text";
string_being_built = concatFunc(string_being_built,&new_statement,offset);
}
Run Code Online (Sandbox Code Playgroud)
因此,在 concatFunc 中,first_string 受到限制(意味着指向的内存不会从其他任何地方更改)。但是,如果我重新分配一个作为其副本的指针,这是否会导致未定义的行为,或者编译器是否足够聪明来适应这种情况?
基本上:当您限制指针参数但随后更改指针时会发生什么。
当您限制指针参数但随后更改指针时会发生什么情况。
这取决于指针如何改变 - 在这种情况下,memcpy()存在 UB 风险。
与char* result = first_string;, 继承restrict的char* restrict first_string。
之后result = realloc(result,2*block);,result与之前一样,访问 viaresult不会与通过second_stringor访问发生冲突, offset or result是新内存,并且访问 viaresult不会与通过second_string或访问发生冲突offset。
然而编译器能否知道 新分配的值result具有上述两个属性之一realloc()?毕竟,realloc()可能是用户定义的函数,编译器不应该假设result现在restrict再具有该属性。
因此memcpy()处于危险之中。
编译器是否足够聪明来适应这一点?
除了警告使用情况之外,我不认为它可以memcpy()。
当然OP也可以用memmove()of来memcpy()避免这个顾虑。
在我看来,一个简化的例子是:
char* concatFunc (char* restrict first_string, char* restrict second_string) {
int block = rand();
first_string = foo(first_string, block);
// first_string at this point may equal second_string,
// breaking the memcpy() contract
memcpy(first_string, second_string, block);
return first_string;
}
Run Code Online (Sandbox Code Playgroud)
或者更简单
char* concatFunc (char* /* no restrict */ first_string, char* restrict second_string) {
return memcpy(first_string, second_string, 2);
}
Run Code Online (Sandbox Code Playgroud)