Others have already answered that your code is valid C++11 and later, but is undefined behavior for earlier versions of C++ and won't even compile in C (ignoring class member fcn calls, of course).  All of which says you should probably use a more explicit form to achieve your desired end.
I also wanted to point out that you likely have a subtle bug in your code when p == j - 1 because you add one but don't mod when you initialize i, making you access beyond the end of the array in that case.
You also never process the element at index p.  Is that really what you want?  If you repeatedly executed this code and none of the other buffers were ready(), then you would keep skipping over checking if buffer[p].ready().
More correct, more universal code (that still doesn't check the element at index p):
int i;
for (i = (p + 1) % j; i != p && !buffer[i].ready(); ++i, i %= j);
if (i != p)
{
  buffer[i].do_something();
  p = i;
}
A version that starts by processing the element at index p, but stops after going over the array at most once:
int i = p;
while (!buffer[i].ready() && (++i, i %= j, i != p));
if (buffer[i].ready())
{
  buffer[i].do_something();
  p = i;
}
There is a subtle point about the above version.  If !buffer[p].ready() when we first enter the loop, we go through the whole array, and none the other elements are ready() either, then we will exit the loop with i == p.  We will then interrogate buffer[p] again asking if it is ready().  So, it is possible to ask buffer[p].ready() twice, which may or may not be important (e.g. - if it has side effects).  Heads up!
Here's a version that avoids that issue, but checks buffer[p].ready() last:
int i = p;
while ((++i, i %= j, i != p) && !buffer[i].ready());
if (i != p || buffer[p].ready())
{
  buffer[i].do_something();
  p = i;
}