Почему формат в 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" пример.