I
Ilya N. Golubev
There is already one function processing pointer values this way. And
there may easily appear more, including wrappers for this function.
For purposes of further discussion, consider simplified function,
`consume'. It has one arg, INBUF, that points to a variable that
points to the first character in the input buffer. The function never
modifies characters pointed to by `*INBUF'. It, however, updates
the `*INBUF' value to point to the byte following the last byte
successfully consumed.
We can declare this function
void consume (const char **);
or
void consume (char **);
Which one is appropriate, wrt semantics of `const' as designed in
current C language standards? In any case, applications may have both
`char *' and `const char *' variables, which must be passed and
updated as described above. In any case, the conversions are be
needed to do such a passing, like this.
void consume (const char **);
/* ... */
char *buf;
consume ((const char **) &buf);
Or
void consume (char **);
/* ... */
const char *buf;
consume ((char **) &buf);
Currently, if T is type, any `T*' value may be assigned to `const T*'
one. This is not the case for assigning `T**' values to `const T**'
ones. Why would allowing this be incorrect / dangerous?
Or should we completely avoid declaring functions with `**' args like
these, and specify them like `write' instead? That is, to take `const
char *' arg and return or otherwise pass to caller a `ssize_t' value
saying how much should be added to said `const char *' value before
passing it to the next call.
The function needs to update `size_t' value in addition to `char *'
one anyway, and this should be also the case for its wrappers. So one
might declare `consume' like this.
typedef struct {
const char *p;
size_t s;
} ciov_t;
void consume (ciov_t *IR);
So that is updates both `IR->p' and `IR->s'.
Never seen such a declarations, however. `writev', in particular,
does not use input structures with `const void *' for data to write.
This will even cause trouble for application writers needing to pass
such a data pointers to `writev'. What would be dangerous / incorrect
in declaring functions this way?
there may easily appear more, including wrappers for this function.
For purposes of further discussion, consider simplified function,
`consume'. It has one arg, INBUF, that points to a variable that
points to the first character in the input buffer. The function never
modifies characters pointed to by `*INBUF'. It, however, updates
the `*INBUF' value to point to the byte following the last byte
successfully consumed.
We can declare this function
void consume (const char **);
or
void consume (char **);
Which one is appropriate, wrt semantics of `const' as designed in
current C language standards? In any case, applications may have both
`char *' and `const char *' variables, which must be passed and
updated as described above. In any case, the conversions are be
needed to do such a passing, like this.
void consume (const char **);
/* ... */
char *buf;
consume ((const char **) &buf);
Or
void consume (char **);
/* ... */
const char *buf;
consume ((char **) &buf);
Currently, if T is type, any `T*' value may be assigned to `const T*'
one. This is not the case for assigning `T**' values to `const T**'
ones. Why would allowing this be incorrect / dangerous?
Or should we completely avoid declaring functions with `**' args like
these, and specify them like `write' instead? That is, to take `const
char *' arg and return or otherwise pass to caller a `ssize_t' value
saying how much should be added to said `const char *' value before
passing it to the next call.
The function needs to update `size_t' value in addition to `char *'
one anyway, and this should be also the case for its wrappers. So one
might declare `consume' like this.
typedef struct {
const char *p;
size_t s;
} ciov_t;
void consume (ciov_t *IR);
So that is updates both `IR->p' and `IR->s'.
Never seen such a declarations, however. `writev', in particular,
does not use input structures with `const void *' for data to write.
This will even cause trouble for application writers needing to pass
such a data pointers to `writev'. What would be dangerous / incorrect
in declaring functions this way?