3 ms·
What makes it tricky to use, and where does it fall short?
by bmh100 10y ago
What makes it tricky to use, and where does it fall short?
- CJefferson 10y agoThere are some weird rules, like: mypair* restrict position = &object->pair; float* restrict position_x = &position->x; Is undefined behaviour, as you can't take a restricted pointer to a child of a restricted pointer in the same scope (the rule isn't quite that simple, but that's part of it). In general, rules about pointers to pointers get complicated, and I've had trouble with them in the past. In general, it's a good idea to try to only use restrict for "leaf" pointers, not intermediate objects, but that does block some optimisations. There is also the obvious problem of people getting carried away, and marking something 'restrict' where they shouldn't have. While 'restrict' is very easy to use on simple structures (like just int*), if you look around you'll find very little, if any, material about using it for complicated nested data structures.
- Someone 10y agoThere's also the fact that restrict is only a promise to the compiler "this function will not be called with aliased arguments", not also a command "do not allow people to call this function with aliased arguments". As far as I know Fortran, at least in its original form, enforced the latter (that was fairly easy to do, as it didn't have dynamic memory allocation, pointers or recursion (the compiler determined the location in memory of all variables))
- greglindahl 10y agoNeither of your options is the actual rule. The actual rule is that when the program runs, there can't be any runtime aliasing. You can totally call a subroutine with several arguments being the same thing, as long as you don't do anything bad inside the subroutine. I'm aware of this because I tried to get the PathScale compiler team to add a warning for incorrect aliasing. That wasn't possible. But I did get a flag which made the compiler obey C aliasing rules for Fortran, and it was part of the "got the wrong answer? run with these flags and if you get the correct answer, your program is not standard-conforming" thingie.
- Someone 10y agoPlease educate me and explain how that contradict anything I claimed, as I don't see it. I claim it is only a promise, you claim you can call it with identical arguments. I don't see a contradiction; making a promise isn't the same as keeping it. Similarly, your argument that it is fine to break that promise as long as you don't do anything bad inside the subroutine, I read as "you sometimes can get away with breaking a promise", but again, that's not the same as not making the promise. What am I missing?
- CJefferson 10y agoThe difference is subtle. Here is a (stupid) example: int chooseone(restrict int* a, restrict int* b, bool c) { if(c) return *a; else return *b; } Here, we can pass the same pointer for a and b, because only one of them is ever accessed in any call to the function.
- Someone 10y agoThanks. I reread http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf, and initially didn't get that from the informal description of restrict given there. It says (section 6.7.3): "An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer." So, it hinges on the meaning of 'accesses'; it is a runtime thing, not a compile-time thing.