C99 restrict keyword & printf

Although I am a C++ programmer, I am interested in issues of the C language.

The ISO C99 standard added a new keyword restrict, and add it in the declaration of many standard functions.
In these functions, there is printf/fprintf/sprintf & co.

printf is now declared as:

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

If I understood correctly the standard, the restrict keyword means that during the execution of printf, the format string (at least bytes that are parsed, that is all bytes) must be accessed exclusively via expressions based on the format pointer, thus I think that:

const char*s="%s";
printf(s,s);

Has undefined behaviour (except if there is some special code which checks whether this case happends, what is improbable). :(

But behaviour of that piece of code was well defined (I guess) in a C89 program.

I think that it would be wrong for the ISO standard, to break compatibility with C89 (even if it would not break much code) only for a stupid optimization on a small-sized argument (format strings are usually very short) of a function which is generally not CPU-bound.

I hope that someone could contradict me, and show me where I am wrong.

Please, say that I am wrong.
[1291 byte] By [SuperKoko] at [2007-11-19 18:30:32]
# 1 Re: C99 restrict keyword & printf
There's a long diatribe by Dennis M. Ritchie here (http://www.lysator.liu.se/c/dmr-on-noalias.html) that managed to keep noalias out of C89. I see that this evil concept has managed to creep back into the language.

Personally, I think that const, volatile and restrict should be tossed out of the language. Programmers shouldn't have to think about these things when writing code. It's too distracting.
googler at 2007-11-9 0:55:52 >
# 2 Re: C99 restrict keyword & printf
Personally, I think that const, volatile and restrict should be tossed out of the language. Programmers shouldn't have to think about these things when writing code. It's too distracting.

I cannot say for the restrict keyword which looks quite dangerous.

But, the const keyword is good (and few languages have a compile-time const checking).
With usage, it is easy to use const without thinking to it.
And it makes the code more autodocumented (even if no code is fully autodocumented), and eases compile-time error checking.

The volatile keyword is quasi-necessary for multithreaded programs.
adding volatile qualifiers cannot make a program break!

tossing the volatile keyword would mean:

Very bad code generation
OR breaking many multithreaded programs.
SuperKoko at 2007-11-9 0:56:51 >
# 3 Re: C99 restrict keyword & printf
I realize there's an element of throwing the baby out with the bath water here, but still, I think it's time to wipe the slate clean. While we're at it, they should also bring back mandatory and very frequent use of gotos.
googler at 2007-11-9 0:57:58 >
# 4 Re: C99 restrict keyword & printf
EDIT: sorry, for the double post
SuperKoko at 2007-11-9 0:58:53 >
# 5 Re: C99 restrict keyword & printf
I think that you were confused by the Dennis Ritchie critique about const.
This critique of const is obsolete, because it was on a basis of semantics of drafts of the standard. These semantics were bad, as Dennis Ritchie showed.
Drafts specified that converting a pointer to const data to a pointer to data leaded to undefined behaviour if the data was subsequently modified.
This undefined behaviour has been removed in the final standard (except if the pointer was truly pointing to a const-object).

Moreover, with C++, casting from a pointer to const to a simple pointer needs an explicit const_cast. As this type of cast operation is exceptionally used, it is easy to figure when it is valid and when it is not.

There is nothing that could lead to undefined behaviour, in putting const specifiers for all non-modified parameters and in const methods.
Thus, that type of constness is always good.

Also, issues of noalias have been resolved with restrict (which has very different semantics).
However, I admit that using restrict is uselessly dangerous for normal programmers (including me).
SuperKoko at 2007-11-9 0:59:57 >
# 6 Re: C99 restrict keyword & printf
tossing the volatile keyword would mean:

Very bad code generation
OR breaking many multithreaded programs.

Another place where eliminating volatile would be disastrous is in low-level device drivers. For hardware registers that can change at any time, you've got to use the volatile keyword, or you risk getting an old value. Next thing you know, your Windows machine has a nice blue screen. :)

I don't think const/volatile is a bad thing to have, because if you think about it, except in these special situations, you don't really have to keep const in mind. No one is holding a gun to your head and telling you to write a const-correct program; it's purely optional, but you do give the compiler the ability to generate a better executable if you write const-correct source code.
Bob Davis at 2007-11-9 1:00:54 >
# 7 Re: C99 restrict keyword & printf
it's purely optional, but you do give the compiler the ability to generate a better executable if you write const-correct source code.

Not really better executable (because const is not a machine-code level promise, but a conceptual promise).
See http://www.gotw.ca/gotw/081.htm

It increases maintainability and readability.
It is the main purpose... and the only effect in truth.

Note : a compiler is able to look at the code and see if a local variable/data (particulary if its address is not taken) is actually modified or not, independently of constness attributes.

The only optimization I can see for constness is the alias optimization (http://www.nullstone.com/htmls/category/aliasqua.htm) which is seldom.

PS: volatile is a low-level thing that make C and C++ (especially C) widely used languages for system and driver development.
Most guys don't need to bother with that.
SuperKoko at 2007-11-9 1:01:57 >
# 8 Re: C99 restrict keyword & printf
Hey, searching a bit on the internet, I found that I read an old draft (January 18 1999 : draft N869).
Draft N877 correct this issue by allowing "aliasing" of restrict pointers provided that the pointed data is not effectively modified (neither by the P-based pointers, nor by other pointers).
And EXAMPLE 3 had been modified to replace undefined behaviour with defined behaviour. :)

In that case, printf behaviour is well defined, even if buffers overlap (including potential buffer overlaps due to string merging of the compiler or linker).
It also solves the case where two different threads (in multithreaded environments) access the same const-data via a restrict pointer (for example memcpy).

Now, I think that C handles adequately restrict pointers.
SuperKoko at 2007-11-9 1:03:04 >