I want to make a macro that when given a type T, will return a pointer type that is readonly when passed to a function, like so:
void foo( readonly_ptr(char) str )
{
// can only read from str, not modify it
}
This proved to be harder than I thought, since simply prepending const
isn't enough.
My current code is:
#define readonly_ptr(T) \
const typeof(T)*
Which works for "simple" types.
But doesn't work with all types.
When given a pointer-to-array type (e.g. int(*)[10]
) it turns it into int(*const*)[10]
which still allows the function to modify the array like this:
void foo( readonly_ptr(int(*)[10]) arr )
{
(**arr)[0] = 1;
}
Similarly for pointer types (e.g. char*
) it turns it into char *const*
which can have its underlying char
s modified.
Is there a way to make a macro that guarantees a readonly parameter?
If not, is there another way to make sure a function won't modify the argument, without having to specify the exact type every single time.
I also tried always passing const void*
every time I needed a readonly, however that is still legally cast-able to a modifiable type.
I guess if your underlying question is whether it is possible to make the memory location immutable in every case the answer is probably no. I don't think there is a way to make something 100% read-only when pointers are involved with a Makro like this.
This might differ between C standards, compilers and systems, but casting away
const
and modifying the value should be undefined behavior. Check out this link. Some systems might just segfault, others will probably work if you try to hack your way aroundconst
with casting. So this will be difficult.If you want to make this pointer-shenanigans at least somewhat difficult, how about creating some API. You could try to pass a function, that does the reading on a memory location you defined before you call
foo
. Then again, you could just copy and afterwards pass it.