Почему формат в printf отмечен как restrict?
Я просто случайно посмотрел на прототип printf
(и других fprintf
класс функций) -
int printf(const char * restrict format, ...);
ключевое слово restrict
если я правильно понимаю, запрещает доступ к тому же объекту через два указателя, если один из них помечен как restrict
.
пример, который цитирует то же самое из стандарта C, -здесь.
одно преимущество маркировки формата как restrict
Я думаю, что это сохранение функции от вероятность того, что строка формата может быть изменена во время выполнения (скажем, из-за %n
формат описателя).
но накладывает ли это большее ограничение? Делает ли это вызов следующей функции недопустимым?
char format[] = "%s";
printf(format, format);
потому что здесь явно есть сглаживание. Почему restrict
ключевое слово добавляется к
2 ответов
cppreference
во время каждого выполнения блока, в котором ограниченный указатель
P
объявлена (как правило, каждое выполнение тела функции, в которомP
является параметром функции),если какой-то предмет, который доступен черезP
(прямо или косвенно) модифицируется, любыми средствами, тогда все доступы к этому объекту (и читает и пишет) в этом блоке должно произойти черезP
(прямо или косвенно), в противном случае поведение неопределено.
(выделено мной)
это означает, что:
char format[] = "%s";
printf(format, format);
хорошо определен, потому что printf
не будет пытаться изменить format
.
единственное, что restrict
делает undefined " запись в строку формата с помощью %…n
пока printf
работает (например,char f[] = "%hhn"; printf(f, (signed char *)f);
).
почему
restrict
ключевое слово добавлен аргумент форматаprintf
?
restrict
- это, по сути, подсказка, которую компилятор может использовать для оптимизации вашего кода.
С restrict
может или не может заставить код работать быстрее, но он никогда не может сделать его медленнее (при условии, что компилятор вменяем), его следует использовать всегда, если:
- использование его вызовет UB
- оно не делает никакое значительное улучшение представления в этом специфическом дело
почему формат в printf отмечен как restrict?
int printf(const char * restrict format, ...);
на restrict
на some_type * restrict format
- это "договор" между вызывающим кодом и функцией printf()
. Это позволяет printf()
предполагать единственно возможные изменения данных, на которые указывает format
происходит то, что функция делает напрямую, а не побочный эффект других указателей.
в данном printf()
состоять из кода, который не связан с изменяющейся строкой формата такими побочными эффектами.
С format
указывает на const
данных printf()
также не разрешается изменять данные. Но это вспомогательная к restrict
характеристика.
рассмотрим патологический код ниже. Это нарушает договор как printf()
может, конечно, изменить состояние *stdout
, что в свою очередь может изменить .ubuf
.
strcpy(stdout->ubuf, "%s");
printf(stdout->ubuf, "Hello World!\n");
@HolyBlackCat хороший "%n"
пример.