Pointers to const in func parameters

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
8 replies · 2K views
Messages
3,372
Reaction score
465
I am not sure that I understand the following:

One of the use cases of pointers to const elements is as function parameters: a function that takes a pointer to non-const as parameter can modify the value passed as argument, while a function that takes a pointer to constas parameter cannot.
http://www.cplusplus.com/doc/tutorial/pointers/

Why would someone pass an input to a function that he/she doesn't want to modify? And suppose that I want to do that, for example a function that runs a loop over [itex]N[/itex] events determined within the main and gives [itex]x=\sum_{i=1}^N i[/itex].

C:
#include <iostream>
#include <cstdlib>
int fun(int* N){
    int i,x=0;
    for(i=1;i<=(*N);i++) x+=i;
    return x; 
}

int main(){
    int myint=5;
    int* N= &myint;
    std::count<< fun(N);
    system("pause");
    return 0;
}

where in my function I don't really modify N at all...
VS just changing the type ##N## points to to const int.

C:
#include <iostream>
#include <cstdlib>
int fun(const int* N){
    int i,x=0;
    for(i=1;i<=(*N);i++) x+=i;
    return x; 
}

int main(){
    int myint=5;
    const int* N= &myint;  //no prob with conversion int*->const int*
    std::count<< fun(N);
    system("pause");
    return 0;
}

They both operate the same. Any feedback?
 
Physics news on Phys.org
The second part of your question answered the first part. You passed N to a function even though you didn't want to modify it. That is very common. You are right that the examples will behave the same. Using a pointer to pass values that you don't want to modify is dangerous, but sometimes it is the practical way to get information to the function. Passing a pointer to a constant is a way to safely guarantee that the function does not modify something that it should not.
 
FactChecker said:
Passing a pointer to a constant is a way to safely guarantee that the function does not modify something that it should not.

This is strange to me... why? because you build the function and you can determine what it should change or not. I think for example that if I tried to modify the N in the function of the const-example I would get an error. I wouldn't get it in the non-const example. But in the end doing so, I would have to modify it by a hand-written command.
eg I insered in the for loop an additional command:
C:
for(...){ x+=i; (*N)--;}
and with the const I got "decrement for read-only location", while it compiled and run propery with a non-const declaration of Npointer.

However I am allowed to change the value of N within the function using the following:
C:
int fun(const int*N){
    int z= 10;
    N= &z
    for [...]
 
ChrisVer said:
This is strange to me... why? because you build the function and you can determine what it should change or not
Things just get too complicated to be absolutely sure. Someone else might have written the function. Or one function calls another, which calls another, which ... Or you wrote the code 3 years ago and are calling it wrong. So it is good to have a way to be sure you can protect input values from being changed. Then the compiler/linker can help you catch these mistakes.
 
Last edited:
ChrisVer said:
and with the const I got "decrement for read-only location", while it compiled and run properly with a non-const declaration of Npointer.
The 'const' is protecting the value at an address from being changed, not the address itself. Parameters are "pass-by-value". The value of the parameter is copied into another memory location and can be changed in the function without changing anything in the calling program. The "const" will make sure that an address coming in is not used to change the value at that memory address. That would change something in the calling program that you are trying to protect. The address itself can be changed without changing anything in the calling program.

An interesting experiment would be to copy the constant address to another local address variable in the function and see if you can change the value at that location using the new address variable.

In your original post, there is no surprise. Neither example tries to change N or *N. The problem occurs when main declares a constant parameter that the function does not treat as constant. The compiler / linker should not allow that.
 
ChrisVer said:
This is strange to me... why? because you build the function and you can determine what it should change or not.
Often you will use functions that you did not build. You want to know if values you pass as arguments might get modified.
 
ChrisVer said:
Why would someone pass an input to a function that he/she doesn't want to modify?
You're looking at things backwards.

Const correctness is a promise from the author of a function to a user of that function that the function in question will not change with the provided data. Suppose you find a function that does exactly what you want, except the signature is some_return_type function_name(some_type* input). (From a users perspective, you would much prefer a signature of the form some_return_type function_name(const some_type* input) ). Now suppose you need to use the unmodified array you provided to that function later on. Without the guarantee that some_function won't change your array, the only available option you have left is to make a complete duplicate of that array before calling that function.

If, on the other hand, the signature is some_return_type function_name(const some_type* input), you can presumably trust the author of that function to be telling the truth. Because that function guarantees that it won't change the contents of the argument to the function, you can dispense with making that unneeded copy.Aside: The const-correct version of that function can always cast the constness away and do whatever it wants to do with the contents of your array. That is widely considered to be a hangin' offense.
 
  • Like
Likes   Reactions: DEvens
For a desktop application 'const' is used as above but for embedded applications 'const' is often used to note that the data is in the 'read-only' (put there to save RAM) part of address space on Princeton architecture microcontrollers Flash or ROM space and/or the compiler might need to use on Harvard architecture microcontrollers Flash or ROM read instructions instead of RAM read instructions to access it. It's a problem with C as it was designed to handle unified addresses that's usually solved with separate functions for RAM and Flash/ROM data or 'fat' pointers in the compiler the mask the problem.
 
Last edited:
  • Like
Likes   Reactions: FactChecker
ChrisVer said:
However I am allowed to change the value of N within the function using the following:
C:
int fun(const int*N){
    int z= 10;
    N= &z
    for [...]

The location of const makes a big difference, and it's a little hard to follow sometimes:

const int * N is a read-only pointer to a writable location in memory
int const * N is also a read-only pointer to a writable location in memory
int * const N is a writable pointer to a read-only location in memory
const int const * N is a read-only pointer to a read-only location in memory
int const * const N is also a read-only pointer to a read-only location in memory

const is used for more than just pointers remember.
 
Last edited: