1

What is the use of declaring arguments of a function in C as const? Does it have an impact on performance?

e.g. why would you prefer f1 to f2? Or f2 to f1?

void f1(const char* arg) {
/* some code */
}

void f2(char* arg) {
/* some code */
}
Fakher Mokadem
  • 1,059
  • 1
  • 8
  • 22
  • 1
    Well... Pointers passed as arguments can be modified in the function. So if they are defined as `const`, then they will always point to the same address... Another reference: https://stackoverflow.com/questions/12291607/passing-arguments-to-functions-with-const-parameters-is-it-faster – PhoenixBlue Aug 08 '18 at 10:26
  • To indicate that it won't be modified, have a look here: https://stackoverflow.com/questions/9419051/declaring-a-pointer-to-const-or-a-const-pointer-to-const-as-a-formal-parameter – Jose Aug 08 '18 at 10:29
  • 1
    @PhoenixBlue of course it is wrong. – 0___________ Aug 08 '18 at 10:29
  • 1
    I would prefer `void f1(const char const * arg)` if `f1()` is guaranteed not to change the input `arg` or its contents – Mawg says reinstate Monica Aug 08 '18 at 10:33
  • @PhoenixBlue Please look at the position of `const`. It does not affect the pointer. – Gerhardh Aug 08 '18 at 10:33
  • @Mawg I think you meant `void f1(const char * const arg)`. – user694733 Aug 08 '18 at 10:34
  • @Mawg you probably mean `void f1(const char * const arg)` – Gerhardh Aug 08 '18 at 10:34

4 Answers4

3

in void f1(const char *arg) the argument arg itself is not const qualified, it is defined as a pointer to an array of char that the function should not modify. This is very useful for the reader to understand at first glance that the function f1 does not modify the string it receives.

For example strcpy is declared in <string.h> as:

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

The array pointed to by the first argument is modified, it is the destination array, the second argument points to the source array, which is not modified.

This type of const qualification is viral: once you define an argument as pointing to a const object, you can only pass it to functions that have similarly const qualified arguments.

Regarding the impact on performance, there is no downside. Some compilers might even benefit from this qualifications and generate better code.

So in your example, if f1 does not modify the array pointed to by arg, unless you need to store f1 in a function pointer of type void (*)(char*) and cannot change this type, I strongly advise to use:

void f1(const char *arg);
chqrlie
  • 131,814
  • 10
  • 121
  • 189
2

const char* arg means that arg is a pointer to a constant char. If you try to change the data that arg points to, you will get an error saying something like: error: assignment of read-only location ‘*arg’. However, you can change the address contained in arg.

Whereas, by dropping the const keyword, you state that the data which arg points to can be changed.

Your preference should be based on your needs. Have a look at this for more information.

In response to your comment: char * const arg means means that arg is a constant (pause a second) pointer to a char. So, you can't change the address contained in arg and you can change the data residing at that address.

babon
  • 3,615
  • 2
  • 20
  • 20
2
void foo(const char *arg)

declares the pointer to the const char. You cant change the referenced object, but you can change the pointer

void foo(char * const arg)

declares the const pointer to the char. You cant change the the pointer, but you can change the referenced object

void foo(const char * const arg)

declares the const pointer to the const char. You cant change the the pointer and the referenced object

declaring parameters allows many compile time optimizations and may have a significant impact on the performance of the generated code.

It is considered a very good practice to use const for the parameters and variables which should not change. Is is called the "const correctness"

Futher reading: restrict keyword.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • I would not overstate possible performance improvements, which are limited. Const correctness is more about improving code quality and reducing programmer errors. – user694733 Aug 08 '18 at 10:48
  • @user694733 And what did I write in my answer? Do you see any downsides of the correct use of `const`? – 0___________ Aug 08 '18 at 10:50
  • No downsides. I just think that *"significant impact on the performance of the generated code."* is a bit much. – user694733 Aug 08 '18 at 10:51
  • @user694733 if you consider the trivial examples yes. Not trivial ones - yes it may have. – 0___________ Aug 08 '18 at 10:56
  • @user if you quote me do it properly and do not change the sense of the sentence: `and may have a significant impact` is not the same as 'have a significant impact' – 0___________ Aug 08 '18 at 10:58
1

You prefer

void f1(const char* arg) 

If you don't want to modify the object pointed by arg through arg. But you can modify the arg itself.

You prefer

void f2(char* arg) 

If you want to modify the object pointed by arg through arg.

klutt
  • 30,332
  • 17
  • 55
  • 95
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
  • I would prefer `void f1(const char const * arg)` if `f1()` is guaranteed not to change the input `arg` or its contents – Mawg says reinstate Monica Aug 08 '18 at 10:33
  • @Mawg: no, your prototype is redundant, you mean `void f1(const char * const arg)` to specify that `f1` will not change the value of the argument itself. Such `const` qualification is useless and obscures the code. – chqrlie Aug 08 '18 at 10:37