Есть ли практическая разница между следующими прототипами?Является ли более высокий уровень волатильности или значительным в прототипе функции?
void f(const int *p);
void f(const int *restrict p);
void f(const int *volatile p);
Раздел C11 6.7.6.3/15 (последнее предложение) говорит, что отборочные на высшем уровне, не рассматриваются для целей определения совместимости типа, т.е. допускается для определения функции имеют различный верхнего уровня квалификаторы по своим параметрам, чем декларация прототипа.
Однако (в отличие от C++) он не говорит, что их полностью игнорируют. В случае const
это явно спорный вопрос; однако в случае volatile
и restrict
возможно может быть разница.
Пример:
void f(const int *restrict p);
int main()
{
int a = 42;
const int *p = &a;
f(p);
return a;
}
наличие restrict
в прототипе Допускает ли компилятор оптимизировать из чтения из a
для return a;
?
Я не думаю, что последнее предложение, о котором вы говорите, относится ко всему абзацу 15, оно только применяется к только что предшествующей фразе. Вначале ясно сказано, что * соответствующие параметры должны иметь совместимых типов *, поэтому для определения прототипа функции необходимо определить параметры. –
@JensGustedt, поэтому вы говорите, что 'void f (int); void f (int const); int main() {} 'плохо сформирован? –
Игнорируя здравый смысл, единственное, что каким-то образом может определить ограниченное определение UB, которое я нахожу в настоящее время, это 6.2.7. P2. Все объявления, относящиеся к одному и тому же объекту или функции, должны иметь совместимый тип; в противном случае поведение не определено. Но это неправедно абсурдно: оно будет одинаково применимо к 'const' (скажем, ABI, используя другой способ передачи аргументов' const'), и это создаст 'void f (const int * restrict); 'different, так как нет' p', который объявлен в первую очередь (поэтому нет объявления). – mafso