Reputation: 787
Here are a couple of C and POSIX functions that need to fetch some data from or put some data into a buffer and tell the caller how much, so they take a pointer to the starting buffer address and write the adjusted pointer there on return:
size_t mbstowcs(wchar_t *restrict pwcs, const char *restrict s,
size_t n); /* for comparison */
size_t mbsrtowcs(wchar_t *restrict dst, const char **restrict src,
size_t len, mbstate_t *restrict ps);
size_t mbsnrtowcs(wchar_t *restrict dst, const char **restrict src,
size_t nmc, size_t len, mbstate_t *restrict ps);
size_t iconv(iconv_t cd,
char **restrict inbuf, size_t *restrict inbytesleft,
char **restrict outbuf, size_t *restrict outbytesleft);
I expect the (principal) meaning of the restrict qualifiers on the buffers is that those functions assume the input and output buffers to not overlap; and for mbstowcs
(that just takes the buffer addresses by value) that indeed seems to be the case.
But why do the rest of the functions take ELEMENT **restrict
pointers and not ELEMENT *restrict *
or ELEMENT *restrict *restrict
pointers? To me these declarations as written would imply that it is the buffer addresses, the ELEMENT *
s themselves as they are stored in memory, that must not alias, which is... probably a bit helpful, yes, but not that as important? These declarations make it look to me like the code
iconv_t cd = /* ... */;
char data[] = /* ... */, *inp = data, *outp = data;
size_t inn = sizeof data, outn = sizeof data;
iconv(cd, &inp, &inn, &outp, &outn);
is valid, which is surely not the intention?
In C17 subclause 6.7.3.1 (Formal definition of restrict
), paragraph 4, we can find a passage that seems vaguely relevant:
[... L]et L be any lvalue that has &L based on P [a restrict-qualified pointer]. If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: T shall not be const-qualified. Every other lvalue used to access the value of X shall also have its address based on P [as defined in a preceding paragraph]. Every access that modifies X shall be considered also to modify P [italics mine], for the purposes of this subclause. [...]
but I cannot for the life of me figure out what the importance of that italicized sentence is.
Upvotes: 1
Views: 142
Reputation: 81159
The semantics of applying a restrict qualifier to anything other than standalone objects of automatic duration whose addresses aren't taken are murky at best. The restrict qualifier offers the most value in cases where its semantics are clearest, and compilers are allowed to effectively ignore the qualifier in cases where the effort required to perform optimizations based upon it would exceed the benefit of such optimizations. Using the qualifier in cases with murky semantics and low payoff is apt to at best be a waste of time, since compilers are likely to simply ignore it, and if they don't ignore it they may interpret in a manner contrary to programmer expectation.
Upvotes: 1