1

After reading the C standard, 6.7.3.1 "Formal definition of restrict", i have the following misunderstanding. I wonder if the following code instantly causes undefined behavior:

void foo(int *restrict p) {
  int *restrict q = p;
}

It is clear that q is assigned the value that is based on another restricted pointer p. What is unclear is if these two pointers are associated with the same block (the function itself), or with different blocks (p with the function itself, q with its compound statement body), because, eg.

int *restrict p;
{
  int *restrict q = p;
}

does not cause undefined behavior (it is OK to create aliasing pointers in sub-blocks).

The top answer in MSVC++ restrict keyword and local variables suggests that int *restrict q = p + 1; would be fine, however [at least, in case of the C standard] it's not true, because expression p + 1 is still based on p.

The definition of the block is in 6.7.3.1 p2:

  1. If [a certain pointer declaration] D appears inside a block and does not have storage class extern, let B denote the block. If D appears in the list of parameter declarations of a function definition, let B denote the associated block. [...]

So is "the associated block" of the function the same thing as the function body in this context? Because i didn't instantly find any explanation of the term "associated block" earlier in the text.

Community
  • 1
  • 1
NoQ
  • 75
  • 6
  • 6.7.3p8 does not even state about declarations in different scopes. Would also not be very intuitively to make that depend on scope. Once you alias an object by two pointers, none of them must be `restrict` qualified. within a function. Relying on anything else than the standard for such details is a bad idea in general. And MS in particular is known not to follow the C standard well (they don't even support the previous versin of the standard, C99). – too honest for this site Jan 29 '16 at 19:17
  • "associated block" wuite clearly refers to the block asociated with the "restrict". Note that nested blocks are also part of their enclosing blocks. Also about UB, search for "associated block", J.2 might shed some light on the subject. Also see 6.2.1p4 – too honest for this site Jan 29 '16 at 19:22
  • The restrict keyword can only be applied to function parameters as far as I'm concerned. – fuz Jan 29 '16 at 19:32
  • @FUZxxl: I dont see that from the standard. 6.7.3.1p7 shows even examples at file-scope. And restricting `restrict` to functions parameters sound unreasonable to me. – too honest for this site Jan 29 '16 at 19:37
  • @Olaf Huch? Wow. Seems like I was misguided. – fuz Jan 29 '16 at 19:38
  • @FUZxxl;: Maybe because they are not much used inside functions (the compiler can analyse the programflow itself) and global variables are often discouraged anyway. Not to forget the qualifier still is seldom used. – too honest for this site Jan 29 '16 at 19:40
  • @Olaf: There are a number of places the qualifier could be used within functions, especially if a pointer variable might get loaded from any of several different sources. – supercat Jul 11 '16 at 17:24
  • @supercat: I think I stated that quite clear in my comment. Inside a single compilation unit, more a single function, the compiler has the full context, so can figure out itself the dependencies. Modern compilers do this since quite some time for the simple reason `restrict` is C99 and (as I mentioned) seldom used (be it lazyness or not knowing as FUZxxI). It does not harm to use, but I question if there is any good apart from potentially getting a warning for a violation (I would not rely on getting one, though). This all does not apply to an **external** interface. – too honest for this site Jul 12 '16 at 01:50
  • @Olaf: From what I can tell, most programmers would like compilers to be faster. While compilers are becoming increasingly sophisticated in their ability to make inferences, such abilities come with significant costs in compilation speed and language semantics. Letting a programmer *tell* a compiler things it otherwise may not know would seem better than requiring compilers to spend time on every build trying to figure them out. – supercat Jul 12 '16 at 14:14
  • @supercat: Strange. Most programmers like to use a high abstraction layer which implies the compiler shall figure out optimisations on its own. If you prefer telling the compiler everything it might or might not know, Asssembler might be the language of choice. Well, I'm quite a control-freak when it comes to programming, but even me prefers a high abstracting language. With LTO there is actually even less need for `restrict`, etc. `restrict` actually is a hack for lack of standardised passing such information from the compiler to the linker automatically. – too honest for this site Jul 12 '16 at 14:27
  • @Olaf: My philosophy is that programmers should tell compilers things the programmer will easily know and the compiler may not, and let the compiler decide what to do with that information. There are many cases where even very loose behavioral guarantees in boundary cases can allow code to be written more efficiently than would otherwise be possible; a low-level language should not force a programmer to write code for operations which are not needed in the machine code for the program to meet requirements. – supercat Jul 12 '16 at 14:45
  • @supercat: Well, I prefer concentrating on the problem, not the compiler. Premature optimisation is commonly accepted a bad design practice anyway. – too honest for this site Jul 12 '16 at 14:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117113/discussion-between-supercat-and-olaf). – supercat Jul 12 '16 at 14:53

0 Answers0