I am attempting some optimization of code, but it is hard to wrap my head around whether "restrict" is useful in this situation or if it will cause problems.
I have a function that is passed two strings (char*) as well as an int (int*).
The second string is copied into memory following the first string, at the position indicated by the int. If this would overrun the allocation of memory for the first string, it must reallocate memory for the first string before doing so. A new pointer is created with the new allocation, and then the original first string pointer is set equal to it.
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;
}
The above function is repeatedly called by other functions that are also using the restrict keyword.
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);
}
So in the concatFunc the first_string is restricted (meaning memory pointed to will not be changed from anywhere else). But then if I am reallocating a pointer that is a copy of that, is that going to cause undefined behavior or is the compiler smart enough to accommodate that?
Basically: What happens when you restrict a pointer parameter, but then change the pointer.
2 * block
in length, you're going to overflow theresult
buffer because you never grow it past2 * block
bytes. – Abstractedchar* result = first_string;
break the restrict rule to begin with? Also note howmemcpy
requires that the memory location do not overlap (otherwise it's undefined behavior). Other than that, I don't think the restrict keyword adds anything here. It may not be wrong (ifresult
wasn't used as an alias), but I don't see any potential optimizations resulting from restricted pointers either. – Masterpiece*offset+=len;
is like*offset=*offset + len;
and can take advantage that the priormemcpy()
did not change the result of the earlier*offset
calls. Withoutrestrict
inint* const restrict offset
,*offset=*offset + len;
would have to referenceoffset
to read*offset
. – Madyconst
inchar* concatFunc (char* restrict first_string, char* const restrict second_string, int* const restrict offset) {
serve no purpose here to demonstrate the issue. Clearer to demo this issue without them. Dropping them does not change the function signature ofconcatFunc()
. – Mady