Reputation: 162
I was wondering and could not find an answer to my question anywhere. Lets say I do have two functions:
void function_B(int * data){
// I am able to modify its content
}
void function_A(int * data){
// I do not want to be able to modify the data nor its content here only pass the pointer to function B, so it can be changed there
function_B(data);
// Nor I want to be able to modify it here
}
I am familiar with the const keyword, but if I make the data and the pointer constant for function A, it cannot be changed also by the function B. How could I write such a code? Is this even possible with c?
Upvotes: 3
Views: 1108
Reputation: 4454
According to your problem statement, function_B()
has to be called within function_A()
, and it shall modify the content pointed to by the pointer data
. This signify that the pointer passed to to function_B()
must not be declared as const
.
As such, if the pointer data
has to come from the caller function_A()
, then it is going to be able to modify what precedes the call to the function function_B()
, and you can't do anything about it.
You can however declare a const
pointer within function_A()
that points to the content of the non-const
pointer data
, and give it the suffix _A
to mean that this pointer shall be used in place of the original pointer data
within function_A()
.
void function_B(int * data) {
// I am able to modify its content
}
void function_A(int * data) {
const int *data_A = data;
// data_A can't change anything...
// I do not want to be able to modify the data nor its content here only pass the pointer to function B, so it can be changed there
function_B(data);
// Nor I want to be able to modify it here
}
Upvotes: 1
Reputation: 17403
One thing you could do is factor out the parts of function_A
that are not allowed to modify the data, something like this:
void func_A_preB(const int *data)
{
// Do stuff with data but don't change it.
}
void func_A_postB(const int *data)
{
// Do stuff with data but don't change it.
}
void function_B(int *data)
{
// Can change data.
}
void function_A(int *data)
{
func_A_preB(data);
function_B(data);
func_A_postB(data);
}
Upvotes: 2
Reputation: 148900
It is questionable design to forbid change in one function but allow it in a called function. But it is indeed allowed by the C standard. As others have already said, the trick is to change function_A
. The simplest change would be:
void function_A(const int * data){
// I do not want to be able to modify the data nor its content here only pass the pointer to function B, so it can be changed there
function_B((int *) data);
// Nor I want to be able to modify it here
}
But it bad design because the prototype of function_A
makes a promise to never change data
and does change it. If you pass an array which was initially declare as const
, you will even invoke undefined behaviour:
const int arr[] = {1, 2, 3};
function_A(arr); // will compile because function_A declared a const param
In function_B
you will try to change a const object which is explicitely UB.
The correct way (which may or not be acceptable for your use case) is to use an auxiliary variable:
void function_A(int * _data){
const int *data = _data; // always valid
// data cannot be used to change anything, but of course _data could
// data[0] = 1; would raise a compilation error
function_B(_data);
// Nor I want to be able to modify it here
}
Upvotes: 1
Reputation: 50775
The only thing you can do is this:
void function_B(int * data) {
*data = 0;
}
void function_A(const int * data) { // << add the const keyword here
*data = 0; // this won't compile (which is what you intend)
function_B(data); // this won't compile either, but that's what you want to do
function_B((int*)data); // but this will compile
}
In function_A
, data
is a const pointer so you cannot modify the data it points to, but you cannot pass it to a function whose parameter is a non const (like function_B
in this example) either.
But you can cast the const
away like in the example above.
Keep in mind that this is still a very questionable design, as casting away a const
defies it's very own purpose as it results in undefined behaviour if the data passed to function_A
is constant.
const int a = 2;
int b = 2;
int main()
{
function_A(&a); // a is constant => results in undefined behaviour
// when function_B tries to modify the data
function_A(&b); // OK
}
Upvotes: 0