1

Suppose I have

struct s {
    int* __restrict__ p1;
    double v;
};

void foo(int* __restrict__ p2, struct s my_s) { /* ... */ }

Do the C++ compilers listed below respect the __restrict__ keywords in this case, and assume memory accesses through p2 cannot affect accesses through p1? Obviously this is compiler-dependent, since restrict is not a C++ keyword.

I'm mainly interested in the answer for gcc 4.9.x and nVIDIA CUDA 7.5's nvcc (when compiling device code of course, not when forwarding to a host compiler). An answer regarding current versions of clang, gcc and msvc++ would also be interesting.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    That's a really obscure thing to use. What's the problem you're trying to solve? – tadman Apr 15 '16 at 20:01
  • The `restrict` keyword is a C construct, not a C++ construct, so it's really a matter of whether the compiler feels like supporting it. – templatetypedef Apr 15 '16 at 20:03
  • @templatetypedef: See edit. – einpoklum Apr 15 '16 at 20:06
  • @tadman: I'm writing some performance-critical function, and instead of passing a pointer I want to pass a pointer-and-another-value - hence the desire for a struct. – einpoklum Apr 15 '16 at 20:08
  • 1
    If I were writing host code, I would use whatever restrict syntax is supported by the particular host C++ compiler. For CUDA device code, I would use the `__restrict__` (not `__restrict`) keyword, which is [documented](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#restrict). If you need to use both interchangeably for host/device usage, I would use a substitution macro similar to those commonly used for `__host__` `__device__`. – Robert Crovella Apr 15 '16 at 20:44
  • @RobertCrovella: Are you referring specifically to the case I mentioned in the question? Because I do use __restrict__ with nvcc, it's the twist of using the struct that worries me. – einpoklum Apr 15 '16 at 20:51
  • The specific case you mention in your question is not valid CUDA device code for `nvcc`, so no, I'm not referring to that case specifically. But with respect to `__restrict__`, the documentation indicates that it "respects" it, and makes no exception for otherwise valid usage in a struct. – Robert Crovella Apr 15 '16 at 21:02
  • @RobertCrovella: I wrote it that way to make the question more generally relevant. Anyway, it wasn't clear to me that my use is actually valid, but from comments here it seems it probably is. – einpoklum Apr 15 '16 at 21:07
  • 1
    Every single one? all the time? Probably not? Why don't you post a question that is answerable. – xaxxon Apr 15 '16 at 21:59
  • @xaxxon: 1. The ones you know about, or the ones I prioritized. 2. Yes, all the time. Compiler behavior doesn't usually change with the phase of the moon... 3. Apparently some do. 4. Consider the possibility that others find it answerable before deciding it isn't. Also, consider being more positive in your criticism. Catching more flies with honey than with vinegar etc. – einpoklum Apr 15 '16 at 22:10
  • 2
    Compilers may choose to "respect" it in some cases and not others. I obviously wasn't suggesting it was based on a randomizer. Maybe you should "consider writing better questions". Don't forget, you're the one trying to get free help. – xaxxon Apr 15 '16 at 23:25
  • @xaxxon: I asked about a pretty specific case IMO. Also, it isn't "free help", its a collective knowledge-sharing endeavor. While it's true that some only ask, and some only answer, most people (or, say, most people with over 100 reputation) do some of both, as well as commenting, editing etc. Finally, I again do not see how you believe I could improve my question. – einpoklum Apr 16 '16 at 09:41
  • @einpoklum You could have provided a specific question about specific code and a specific compiler version. Of course, then you could have probably known the answer without even having to ask. Your question boils down to "has every C++ compiler ever made - and ever version of every c++ compiler ever made - and every compiler yet to be made, since it's difficult for people to know what versions people are referring to when answering - support a keyword in every single situation that could ever happen". No one can possibly answer that question, which is why I voted to close as too broad. – xaxxon Apr 16 '16 at 23:12
  • @xaxxon: I have asked a specific question about a specific code, and even though I wanted an answer regarding several compilers, I did focus it on two of them. Still, to change the impression I'm editing the title and the body to not make the question be about every compiler. Also, if you would have just initially commented "I marked your question as being too broad, especially since you're asking about every possible C++ compiler. Focus it more please" I would have just narrowed it earlier instead of arguing with you. – einpoklum Apr 16 '16 at 23:25

2 Answers2

2

GCC seems to indicate yes, but I would imagine under the hood it's being all brainy about these types of things and may completely ignore the fact that the keyword is present.

I'd also be willing to bet that if you profile your method with and without the restrict keywords, there'd be little to no difference.

If you do this I'd love to know the results.

There's also this answer which may be interesting to read.

Lastly, there's this blog which seems to indicate the nvcc supports the keyword.

Now I'm really curious about the results of profiling your code.

Community
  • 1
  • 1
fetherolfjd
  • 276
  • 1
  • 11
  • I don't think any of the places you linked to actually suggest `__restrict__` is respected when applied to struct/class members, just that it is supported in general. I might take the time to check the compiled code sometime. – einpoklum Apr 16 '16 at 08:28
0

Microsoft C++ AMP (with MSVC++ 2015)

__restrict__ on pointers which are struct members is officially unsupported (emphasis mine):

The following are not allowed:

  • Recursion.
  • Variables declared with the volatile keyword.
  • Virtual functions.
  • Pointers to functions.
  • Pointers to member functions.
  • Pointers in structures.
  • Pointers to pointers.
  • goto statements.
  • Labeled statements.
  • try, catch, or throw statements.
  • Global variables.
  • Static variables. Use tile_static Keyword instead.
  • dynamic_cast casts.
  • The typeid operator.
  • asm declarations.
  • Varargs.

Microsoft Visual C++ 2015

In general rather than AMP C++ code, it's much less clear what MSVC supports. We see an example of __restrict__ being used in a union declaration - so not just a modified on a paremeter of a function - but the semantics are different that you would have for use in a struct.

einpoklum
  • 118,144
  • 57
  • 340
  • 684