mage_hat
mage_hat

Reputation: 159

What is type* volatile* name = value?

I stumbled upon something very strange in the c++ syntax. A volatile* type.

This is the code that I found (in the Qt-library):

void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
{
if (receiver == 0) {
    qWarning(""QCoreApplication::postEvent: Unexpected null receiver"");
    delete event;
    return;
}

QThreadData * volatile * pdata = &receiver->d_func()->threadData; 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ WHAT IS THIS???
QThreadData *data = *pdata;
if (!data) {
    // posting during destruction? just delete the event to prevent a leak
    delete event;
    return;
}

// [...]
}

What I understood form this:

So these are my questions:

Upvotes: 2

Views: 240

Answers (2)

Vaughn Cato
Vaughn Cato

Reputation: 64308

The declaration QThreadData * volatile * pdata means that pdata is a pointer to a volatile pointer to a QThreadData.

In general, volatile means that the object in can change in ways beyond the compiler's control. For example, if it is stored in memory that is written to by other hardware. This means that the compiler must read the value from memory every time that it is needed instead of making the assumption that if it has read the value before and it hasn't made a change to that memory location, that the value is still the same.

So in this case, pdata itself is not volatile. This means the compiler is allowed to assume that pdata won't change unexpectedly. However, what pdata points to can change unexpectedly, and what it is pointing to is another pointer. Furthermore, what that other volatile pointer is pointing to (the actual QThreadData) is not itself volatile.

In C++, const and volatile are treated very similarly. They both indicate that the object has some special property. By requiring these properties to be carried along with the type, certain mistakes can be more easily avoided. This is easier to see for const, but the same logic applies for volatile. For example

void f(int *p)
{
    *p += 2;
    *p += 3;
}

int main()
{
    volatile int a = 5;
    f(&a); // error: can't convert volatile int * to int *
}

Since the function f is compiled separately from the function main, the compiler wouldn't know, when it is compiling the function f, that it should not assume that *p won't change unexpectedly. Without this knowledge, it might change the code to effectively be

*p += 5;

but this would be wrong, since *p might change between the two additions.

Upvotes: 6

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385098

To help fix your confusion, the first thing you should know is that you have a double-pointer type.

The next thing to say is that volatile-ness is part of a type just like const-ness is part of a type: together this fact is called cv-qualification.

[C++11: 7.1.6.1/7]: [ Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. _ — end note ]_

The phrase volatile * isn't any one specific thing: it is two tokens within the type that could mean a number of things.


In this case, you have a QThreadData* volatile*, which is the "pointer to volatile pointer to QThreadData" type. Read it from right-to-left.

If you stripped the volatile out, you'd be left with a QThreadData**.


If you wanted a more simple example, here's two:

int volatile x = 5;
volatile int y = 6;

See, just like const, here we can play with the order of the cv-qualifier a little because there's no ambiguity.

Let's step up the example a little:

int volatile* p = new int volatile(5);

Now we have a pointer to an int volatile (again, the same as a volatile int). The volatile applies left-wards; that is, to the int, not the *.

But we could also have a volatile pointer! Let's say, a volatile pointer to a non-volatile int:

int* volatile p = new int(5);

And I have no idea what you mean by "property".

Upvotes: 6

Related Questions