Does C++11 add the C99 restrict specifier? If not, why not?
Asked Answered
H

5

33

restrict is a C99 feature which is getting a lot of attention lately by allowing the compiler to perform "previously-fortran-only" optimizations to pointers. It's also the same keyword announced by Microsoft recently to be the underpinnings of the C++AMP specification.

Is that keyword actually in the FCD? If not, is there a specific reason it was omitted?

Halophyte answered 22/6, 2011 at 3:21 Comment(7)
Its use in C++AMP is quite different from its use in C99: in C++AMP it is used as a postnominal qualifier on a function, similar to how const or volatile are applied to a member function. (e.g. []() restrict(direct3d) {}.)Distress
I searched for C++AMP and got information about cyclic AMP. Oh, biology...Respite
Maybe it might help future readers to say what restrict means? (I know it means you are claiming that the pointed-to object is not aliased, but some people might not...)Platypus
@James: That is true -- however, they're piggybacking off the same keyword, and they've taken care to avoid conflicting with the C99 use of restrict, so that the spec can more simply be implemented by compiler vendors that support C99 as well.Halophyte
@Mehrdad: channel9.msdn.com/posts/… -- It's basically a way to run C++ in GPGPU scenarios (though the language changes it makes pave the way for e.g. cloud computation as well)Halophyte
@crosstalk: 1. I'd assume readers are smart enough to use Google. 2. You just kind of took care of the problem in your comment. :)Halophyte
iirc, both gcc and msvc support __restrict in c++ codeSacellum
P
15

One argument is that C needs restrict more than C++, because many operations are done with pointers to primitive types and therefore C code has more aliasing problems than C++.

The aliasing rules say that pointers to different types cannot alias, so if the parameters to a function are of different class types they just cannot overlap.

In C++ we also have the valarray family of classes that are supposed to handle arrays of primitive types that are not allowed to alias. Not that it is used much...

Adding yet another way to resolve some aliasing problems, obviously didn't excite the committee enough.

Pericope answered 22/6, 2011 at 15:41 Comment(3)
There is just one std::valarray class template. And I am not exactly sure what this has in common with restrict; the point of valarray is number crunching, e.g. valarray<float> a,b,c;...; a = a + (b-a)*c;. The GNU implementation by Gabriel Dos-Reis is indeed a good one (based on expression templates). But I really don't know why it is related to restrict, or at least, it is not more related to restrict than e.g. vector or deque.Maliamalice
There are several templates in the <valarray> header, all used to handle the arrays in different ways. The connection to restrict is that the C++ compiler can assume that the data in the valarrays are never aliased.Pericope
I must still say that I hear for the first time of this motivation; the same could be said about <algorithm> (and some others), which assume no aliasing, too. While you are of course right that they are based on "restricted data", I remind the point of valarray to be the one to bring number crunching and science to C++.Maliamalice
A
20

The only mention of restrict in the C++11 FDIS is on §17.2 [library.c]:

The descriptions of many library functions rely on the C standard library for the signatures and semantics of those functions. In all such cases, any use of the restrict qualifier shall be omitted.

So restrict is not in C++11.

Astronaut answered 22/6, 2011 at 3:28 Comment(9)
Any idea why they're not just adding restrict (as specified in C99) to C++0x? If they want to add C99 features to the language (which I'm not saying they necessarily should do, but this one seems pretty good) this would seem like the time to do it.Sigh
@Chris: I answered your question 2 minutes before you asked it. Our time machine seems to will have been working.Astronaut
@Chris: Generally the standards committee was kind of against adding C99 features -- for example, we don't have Variable Length Arrays either -- namely because most of what was added in C99 makes sense for a C world, but does't really make sense for a C++ world. (For example, VLAs were not added because the standard already defines vector) However, restrict is one of those cases that I think could have been useful in both languages.Halophyte
@Billy - vector (probably) doesn't allocate on the stack like VLAs do so it's not quite the same (though I don't think VLAs were a terribly good idea in C either) but that does make sense for things like complex.Sigh
@Chris: I never said that vector and VLAs did the same thing -- just that vector is why VLAs aren't added. (Really, for the average user it's a better solution simply because you don't have strange, hard to debug stack overflow problems)Halophyte
@Billy - I never use VLAs for that reason - malloc and free are easier. It would be nice if, for the few times that variably-sized stack allocations were needed, C (and perhaps C++) had a less buggy, more reliable way of doing it. I'd rather see a standard alloca-type function than new syntax.Sigh
@Chris: It would be impossible to use something like that from C++. (How do the objects created get their destructors called!) I think VLAs are better than alloca, because they are type safe (while alloca is not).Halophyte
A std::vla template class would solve both the destructor and the type-safety problems. I think there's one in boost.Astronaut
@Martinho: That's certainly not superior to VLAs in the language though.Halophyte
P
15

One argument is that C needs restrict more than C++, because many operations are done with pointers to primitive types and therefore C code has more aliasing problems than C++.

The aliasing rules say that pointers to different types cannot alias, so if the parameters to a function are of different class types they just cannot overlap.

In C++ we also have the valarray family of classes that are supposed to handle arrays of primitive types that are not allowed to alias. Not that it is used much...

Adding yet another way to resolve some aliasing problems, obviously didn't excite the committee enough.

Pericope answered 22/6, 2011 at 15:41 Comment(3)
There is just one std::valarray class template. And I am not exactly sure what this has in common with restrict; the point of valarray is number crunching, e.g. valarray<float> a,b,c;...; a = a + (b-a)*c;. The GNU implementation by Gabriel Dos-Reis is indeed a good one (based on expression templates). But I really don't know why it is related to restrict, or at least, it is not more related to restrict than e.g. vector or deque.Maliamalice
There are several templates in the <valarray> header, all used to handle the arrays in different ways. The connection to restrict is that the C++ compiler can assume that the data in the valarrays are never aliased.Pericope
I must still say that I hear for the first time of this motivation; the same could be said about <algorithm> (and some others), which assume no aliasing, too. While you are of course right that they are based on "restricted data", I remind the point of valarray to be the one to bring number crunching and science to C++.Maliamalice
N
15

http://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/

Not only the VC++ team, but also the ISO C++ standards committee, considered adding restrict to VC++ and ISO C++, respectively. Although it was specifically suggested for ISO C++11, it was rejected, in part because it’s not always obvious how it extends to C++ code because C++ is a larger language with more options and we would want to make sure the feature works correctly across the entire language.

Nicaragua answered 22/5, 2012 at 18:30 Comment(1)
So IOW they weren't keen on C99 as they weren't present on the comittee, and despite implementing __restrict they didn't want to get sucked into doing a load of work which didn't benefit their interests, but a subset of C community who wanted compilers to be able to better optimise (often numerical) code. Now with C11, back on the C standard comittee, they've declared victory and made lots of C99 stuff optional. C library implementors, always had leeway via assembler or carefully tuned C to ignore the aliasing problem, in a way that a C optimising compiler cannot. (see Herb Sutter on C99)Celestine
T
5

Don't think it's in C++1x (unfortunately time has long run out for 0x...!) but at least msvc and g++ support it through __restrict and __restrict__ extensions. (I don't use gcc much, I think that's the correct extension).

To work properly with C++ I feel that we would also need restricted references, not just pointers, maybe along the lines of my question C++ aliasing rules. Not sure if some of these considerations might be holding things up...

Tanning answered 22/6, 2011 at 3:33 Comment(9)
Nitpick: there is no C++1x. C++0x was the working name of C++11. That names was not changed. Also, given that we can have new standard before the end of the decade, C++1x may end up being the working name for the C++ that comes after C++11.Astronaut
I think I was trying to be funny. I guess the fact that a whole decade has changed isn't that funny anyway...Tanning
The in-joke is that the x is a hexadecimal number, so we're still OK ;)Mignonne
@Darren: As far as I am aware, GCC will accept plain use of C99's restrict in C++ (so long as you don't do things to prevent it from doing so, e.g. specifying -pedantic). I believe MSVC++ implements it as __restrict.Halophyte
@Billy - Off topic, but I always hate macro names that start with double underscores but don't end with them.Sigh
@Chris: Erm... some of us hate ones that end with double underscores too. At least MSVC is relatively consistent about it (all of it's nonstandard extensions are double underscore'd ... GCC has extensions everywhere (though you can turn them off) )Halophyte
@Billy - I just prefer __macro__ to __macro. It looks cleaner to me. Either way I agree that GCC has some dumb ideas about how to extend the C language (see sizeof(void) for starters). Just wish these things were off by default.Sigh
@Chris: The __ things are not macros.Halophyte
@Billy - It was an example. ;)Sigh
S
2

I will take a crack at "why not?"

restrict is basically just an assertion that the compiler cannot verify. (Or more precisely, when the compiler can verify it, the assertion itself is not helpful.) This is just not the sort of thing that the C++ committee is going to like. C++ has always tended to assume "sufficiently smart compilers"; heck, look at the hideous performance of the most trivial C++ libraries before the compilers caught up.

I also suspect the committee felt that defining restrict semantics precisely in the presence of all the other C++ features (references, rvalue references, blah blah blah) would be non-trivial.

So, non-trivial to specify + "a sufficiently smart compiler doesn't need it" = NAK.

Sixteenmo answered 22/6, 2011 at 16:1 Comment(3)
Personally I would argue the "sufficient smart compiler doesn't need it". The way I see it if we have sufficient smart compilers restrict is even more useful then if the compiler needs it. It won't help optimization, but it would enable the compiler to detect more errors. Code which wouldn't work in the case of pointer aliasing isn't that rare, so a way to signal the compiler that the code is wrong when called with aliased pointers would make sense. Of course the fact that dumb compilers can't do that might work against that feature.Footwall
This answer is nonsense. A restrict qualifier is an interface constraint that cannot be verified without whole program analysis. Whole program analysis is not practical for large projects and shared libraries would still be useful even if it was.Dehlia
Furthermore.. what about __restrict in Visual C (GNU __restrict__) .. why could they do __restrict but not the prettier restrict. Bit of a give away isn't it? IIRC somewhere Stroustroup comments about avoiding new keywords and that restrict wasn't felt important enough in C++ to justify the namespace pollution. Of course, that C99 was a standard comittee which met without some key C++ players, means C++ comittee valued C/C++ compatability less than their own priorities (often commercial interests).Celestine

© 2022 - 2024 — McMap. All rights reserved.