Ilya N. Golubev schrieb:
> 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?
Have a look at the comp.lang.c FAQ, especially
http://c-faq.com/ansi/constmismatch.html
BTW: I'd rather use the "secure" form of "const char **" and have
no cast, i.e.
char *buf;
const char *cbuf;
....
cbuf = buf;
consume(&cbuf);
Avoiding the cast can help you find errors like
consume(cbuf);
which is not possible for
consume((const char **)buf);
> 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.
Note that in the context of standard C, there is no "ssize_t" but
there is in POSIX. From the following, I guess that you really mean
size_t.
> 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?
I am not sure whether I understood you correctly.
Do you want to modify data pointed to by a pointer to const type?
This is most of the time a bad idea; if you can guarantee that
you had a pointer to unqualified type to start with, then
"removing the const" may work. If the data was const qualified
from the start, it may well reside in some sort of non-writable
memory.
Or do you want to read data pointed to by IR->p?
The "updates" throws me off, to be honest.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.