Hi,
my attention was directed at the gprs_shift_v_fixed() function:
int gprs_shift_v_fixed(uint8_t **data, size_t *data_len, size_t len, uint8_t **value)
It advances the *data pointer and returns a *value pointer. So it could technically be consting much more aggressively. However, the compiler warnings confuse me.
I've created this test code to illustrate; the ints should be treated read-only by func():
void func(const int **yyy) { (*yyy) ++; }
int main(void) { int y[2] = {23, 42}; // mutable "by coincidence" int *yy = y; func(&yy);
return *yy; // returns 42 }
The idea is that yy is a pointer to a mutable int. func() expects a const int, but what harm could be done by passing a mutable-int pointer as an immutable-int pointer. Apparently this harm:
check.c: In function ‘main’: check.c:10:14: warning: passing argument 1 of ‘func’ from incompatible pointer type func(&yy); ^ check.c:1:6: note: expected ‘const int **’ but argument is of type ‘int **’ void func(const int **yyy)
Changing yy to a pointer-to-const-int clears the warning:
const int *yy = y; func(&yy);
I'm expecting the const to apply to the int pointed at, so I should be able to modify the pointer while the compiler shouldn't waste a thought at whether the int pointed at is const or not. func() is stricter, not less strict than y[].
To further illustrate, this would make the pointer address itself immutable, which is not what I want:
int * const yy = y;
I just want to declare the underlying int data to be unchangeable by func(), not caring whether the caller passes a const int or a mutable int buffer.
Is the compiler merely nitpicking or am I getting something wrong fundamentally?
Thanks!
~Neels
Hi,
On 26.01.2016 15:01, Neels Hofmeyr wrote:
my attention was directed at the gprs_shift_v_fixed() function:
int gprs_shift_v_fixed(uint8_t **data, size_t *data_len, size_t len, uint8_t **value)
It advances the *data pointer and returns a *value pointer. So it could technically be consting much more aggressively.
Yes it could if it was about plain information extraction. But these functions are used to get pointers to modifiable parts of the data for later patching.
So ideally there were two functions, one like the above, and another with the signature gprs_shift_v_fixed_const(const uint8_t **data, size_t *data_len, size_t len, const uint8_t **value)
Yes, C is not optimal for providing such a family of functions.
However, the compiler warnings confuse me.
[...]
check.c: In function ‘main’: check.c:10:14: warning: passing argument 1 of ‘func’ from incompatible pointer type func(&yy); ^ check.c:1:6: note: expected ‘const int **’ but argument is of type ‘int **’ void func(const int **yyy)
Changing yy to a pointer-to-const-int clears the warning:
const int *yy = y; func(&yy);
[...]
I just want to declare the underlying int data to be unchangeable by func(), not caring whether the caller passes a const int or a mutable int buffer.
Is the compiler merely nitpicking or am I getting something wrong fundamentally?
Perhaps http://stackoverflow.com/questions/28062095/pass-a-two-dimensional-array-to-... sheds some light on that.
Jacob
On Tue, Jan 26, 2016 at 05:25:16PM +0100, Jacob Erlbeck wrote:
Yes, C is not optimal for providing such a family of functions.
Sheesh.
I'm kinda disappointed now. It seems C++ has the same kludge, though I thought I remembered to have used <type> as const <type> implicitly before... maybe some old memory from Java times long passed...
Perhaps http://stackoverflow.com/questions/28062095/pass-a-two-dimensional-array-to-... sheds some light on that.
Thanks for the link! That one evaded me while searching.
And thanks for nothing, C *sulk* ;)
~Neels