Why is the format in printf marked as restrict?

旧街凉风 提交于 2019-12-01 16:31:19

cppreference

During each execution of a block in which a restricted pointer P is declared (typically each execution of a function body in which P is a function parameter), if some object that is accessible through P (directly or indirectly) is modified, by any means, then all accesses to that object (both reads and writes) in that block must occur through P (directly or indirectly), otherwise the behavior is undefined.

(emphasis mine)

It means that:

char format[] = "%s";
printf(format, format);

Is well-defined because printf won't attempt to modify format.

The only thing that restrict makes undefined is 'writing to the format string using %…n while printf is running' (e.g. char f[] = "%hhn"; printf(f, (signed char *)f);).

Why was the restrict keyword added to the format argument of printf?

restrict is essentially a hint the compiler might use to optimize your code better.

Since restrict may or may not make code run faster, but it can never make it slower (assuming the compiler is sane), it should be used always, unless:

  • Using it would cause UB
  • It makes no significant performance improvement in this specific case

Why is the format in printf marked as restrict?

int printf(const char * restrict format, ...);

The restrict in some_type * restrict format is a "contract" between the calling code and the function printf(). It allows the printf() to assume the only possible changes to the data pointed to by format occur to what the function does directly and not a side effect of other pointers.

This allows printf() to consist of code that does not concern itself with a changing format string by such side effects.

Since format points to const data, printf() is not also allowed to change the data. Yet this is ancillary to the restrict feature.


Consider pathological code below. It violates the contract as printf() may certainly alter the state of *stdout, which in turn can alter .ubuf.

strcpy(stdout->ubuf, "%s");
printf(stdout->ubuf, "Hello World!\n");

@HolyBlackCat has a good "%n" example.

Key: restrict requires the calling code to not pass as format, any pointer to a string that may change due to printf() operation.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!