La règle générale pour tous les qualificatifs de type est que vous pouvez convertir implicitement et en toute sécurité un pointeur en type en un pointeur qualifié en type. Ceci est garanti par 6.3.2.3 ainsi que par les règles d'affectation simple 6.5.16.1 (qui s'appliquent lors du passage de paramètres). Il en va de même pour tous les qualificateurs : const
, volatile
, restrict
y _Atomic
.
Cela ne veut pas dire que vous pouvez faire l'inverse. Vous ne pouvez jamais abandonner un qualificatif implicitement, vous devez utiliser un cast explicite. Et lorsque vous le faites, vous invoquez un comportement défini par l'implémentation.
Dans ce cas, le plâtre est parfaitement sûr : func((double*const *)q);
.
Notamment, restrict
est le plus utile lorsqu'il est utilisé sur des paramètres de fonction et que vous appelez ces fonctions depuis une autre unité de traduction. Pour utiliser restrict
dans une portée locale n'est probablement pas très significative, car le compilateur peut facilement déduire si les variables impliquées dans une expression pointent à des adresses différentes ou à la même.
Globalement, il s'agit d'un "contrat" entre le programmeur et le compilateur, dans lequel le programmeur promet de ne pas accéder aux données pointées par le biais d'une autre variable. Le programmeur peut cependant facilement rompre ce contrat en rejetant la variable restrict
et tout peut arriver.