Why doesn't strcpy use a const pointer for dest?
Asked Answered
M

5

6

Is there a reason strcpy's signature is this:

char *strcpy(char *dest, const char *src);

instead of this?

char *strcpy(char *const dest, const char *src);

As far as I know, the function will never change the pointer.

Am I misunderstanding what const pointers should be used for? In my mind, when a function I write accepts a pointer which won't be changed (via realloc, etc.), then I mark it as a const pointer so the caller can be assured their pointer won't be moved on them. (In case they have other structs/etc. referencing that pointer location that would become outdated)

Is that an OK practice, or will it have unintended consequences?

Mither answered 23/1, 2017 at 16:19 Comment(2)
I think a constant can only be initialized/assighned/defined once or is defined upon declaration.Americanize
Not only the function will never change the pointer., but there is no way strcpy could change dest anyway even without const.Cypress
C
11

The source code for strcpy is very roughly this:

char *strcpy(char *dest, const char *src)
{
  while (*dest++ = *src++);
}

Here we actually do modify dest but this has no consequence for the caller because inside the strcpyfunction, dest is a local variable.

But following code won't compile because dest is const:

char *strcpy(char * const dest, const char *src)
{
  while (*dest++ = *src++);
}

we would need to write this:

char *strcpy(char * const dest, const char *src)
{
  char *temp = dest;
  while (*temp++ = *src++);
}

which introduces a non necessary temp variable.

Cypress answered 23/1, 2017 at 16:25 Comment(2)
Note: the 3 examples do not return value for a char *strcpy() function rendering them UB - of course they are rough. It will be interesting to see code without a "non necessary temp variable" that returns the original dest as specified in the C library.Hedrick
@chux you are perfecly right, but it's just for demonstration purposes.Cypress
F
3

Qualifiers on function arguments are completely ignored in declarations (prototypes). This is required by the C language, and it makes sense, because there is no possible meaning such qualification could have to callers of the function.

In the case of const char *src, the argument src is not what's qualified; the type it points to is qualified. In your hypothetical declaration for dest, the qualifier applies to dest and is thus meaningless.

Freeforall answered 23/1, 2017 at 16:27 Comment(0)
H
2

char *foo(char *const dest, const char *src) { ... } means the pointer dest will not change in the body of the function.

It does not mean the data pointed to by dest will or will not change.

const char *src assures the calling code that the data pointed to by src will not change.

In calling a function like strcpy(d,s) or foo(d,s), the calling code does not care if the function changes its copy of the pointer. All the calling code cares about is if the data pointed to by s or d is changed and that is control by the const of the left side of *

char *dest,     // data pointed by `dest` may or may not change.
const char *src // data pointed by `src` will not change change because of `src`.
Hedrick answered 23/1, 2017 at 18:21 Comment(0)
B
1

It is meaningless to mark it as const as you suggest. In C, function arguments are passed as copy. It means that the variable dest inside strcpy() is actually a new variable (pushed on the stack), which holds the same content (here, the address).

Look at this function prototype:

void foo(int const a);

This has no semantic value, because we know that the original variable a that we passed to foo() can't be changed because it is a copy. Only the copy will potentially change. When foo return, we are guaranteed that the original variable a is unchanged.

In function parameters, you want to use the keyword const only if the function could actually persistently change the state of the variable. For example:

size_t strlen(const char *s);

This marks the content of the variable s (ie, the value stored at the address s points to) as const. Therefore, you are guaranteed your string will be unchanged when strlen returns.

Bernardinebernardo answered 23/1, 2017 at 17:31 Comment(0)
J
-1

As far as I know, the function will never change the pointer.

Yes, but you can. You are free to change the pointer. No need to make dest pointer const.

For example:

int main(void)
{
    char *s = "Hello";
    char *d = malloc(6);

    strcpy(d, s);
    puts(d);
    strcpy(d, "World");
    puts(d);
}
Jeraldinejeralee answered 23/1, 2017 at 16:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.