質問: q[i] + r[i]; } ``` の場合、 > > h(100, a, b, b) has defined behavior, because array b is not modified within function h. > > > って書いてある。 (この場合第1引数と第2・3引数との制約で、第2と第3引数の間の制約ではないとも言える。) 理由として変更がされないからということであれば、 動作未定義かどうかは単にパラメータ(のポインタが同一オブジェクトを指すかどうか)だけでは(実装を知らない使用者側としては)判断ができずに、その実装によることになる。(実際には動作の説明が必要不可欠) (逆に言えば、未定義動作(期待しないような動作)するような状況になったら、動作未定義だったのだなとわかるw) だから、`memcpy(p, p, 0)`の場合も、明らかに変更するような動作が行われないので、defined behaviorだと言える。
回答: `strtol` の第一引数は `char` (とその後ろに連続してある char) へのポインター (i.e. input へのポインター) であり、第2引数は `char *` へのポインター (i.e. p へのポインター) です。よってそれぞれのポインターが指してる先は別のオブジェクトなので、restirct 制約に違反してないように見えます。restrict 制約は、そのポインターが指してる先しか影響しない(ポインターのポインターだからといって、ポインターの先のまた先を見ない)はずです。 手元に規格書がないのですが、 によれば > > If the declaration of intent is not followed and the object is > > accessed by an independent pointer, this will result in undefined > > behavior. > > > と書いてあるので、制約に違反するプログラムの動作は未定義のようです。 **追記** そもそも型が違う時点で `restrict` は意味無いでしょう。 によれば > > なお「異なる型へのポインタ型同士」の場合は、restrictキーワードによる指示がなくてもstrict aliasing ruleに基づいて、コンパイラは互いに他方のaliasにならないと仮定した最適化を行う。 > > > とありますし。意味があるかどうかはおいておくとして、無理やり ``` int main(void) { char *p = (char *) malloc(sizeof(char *)); p[0] = '0'; p[1] = '\0'; long l = strtol(p, (char **) p, 10); ``` とすれば、`restrict` 制約に反するコードになるかもしれません。