简体   繁体   中英

pointers in a volatile struct in C

Say I have a struct

typedef struct A{

int a1;
int *a2;

}A_t;

Now if I declare an instance of this struct to be volatile -

volatile A_t trial;

And I use a volatile pointer to access this volatile struct.

volatile A_t *ptrToTrial = &trial;

If I try to do this:

int *ptrToField = ptrToTrial->a2;

Should ptrToField be volatile as well? Would the compiler know that prtToField is volatile without explicit mention because it is accessed through ptrToTrial which is volatile?

Also if there is a function -

function trialFunction(A_t *trialptr)
{
     int *p = trialptr->a2;

}

If we call this function with the volatile ptr declared above -

trailFunction(ptrToTrial)

I get an error: volatile A_t* is incompatible with parameter of type A_t .

So if I change the function definition to include volatile , I do not see an error.

function trialFunction(volatile A_t *trialptr)
{
     int *p = trialptr->a2;

}

Shouldn't the compiler also complain about the pointer p - because p is non-volatile and trialptr->a2 is volatile?

Should ptrToField be volatile as well?

With your definition of struct A , the thing pointed to by member a2 is not declared to be volatile . That a given instance of struct A is volatile implies that its member a2 (the pointer) is volatile , but not that the thing it points to is volatile . This is the difference between int * volatile (equivalent to the actual case) and volatile int * .

The initialization you describe ...

int *ptrToField = ptrToTrial->a2;

... initializes ptrToField with the value of pointer ptrToTrial->a2 . Because ptrToTrial points to a volatile object, the program must load the pointer (a member of that volatile object) from main memory. Because the thing pointed to is not (declared to be) volatile, however, no information is lost and no (new) risk is inherent in declaring the type of ptrToField 's target as a plain int . Certainly there is no advantage in declaring ptrToField itself as volatile.

Do also note, in case it is unclear, that the name of your variable ptrToField is inconsistent with the use to which you put it. You do not initialize it to point to a member of your struct ; rather, you initialize it as a copy of a member of your struct .

Would the compiler know that prtToField is volatile without explicit mention because it is accessed through ptrToTrial which is volatile?

It is not required to exercise any such knowledge it might have, and that knowledge in any case would be likely to be very limited in scope. It knows how that variable was initialized, but it may be difficult to predict when and how its value might thereafter be modified. In any case, any information not carried by the declared type of the variable is not relevant to the standard C semantics of your program.

Shouldn't the compiler also complain about the pointer p - because p is non-volatile and trialptr->a2 is volatile?

No, because although trialptr->a2 is volatile, there is no problem with reading its value (at some given point in time) and assigning that value to another variable. Object values are bit patterns, they are neither volatile nor non-volatile -- that's a characteristic of their storage, as communicated via the lvalues by which they are accessed.

Please be noted that int *a2; in your struct A is not volatile. So

int *ptrToField = ptrToTrial->a2;

ptrToField is not volatile .

trailFunction(ptrToTrial) gets error because the function trailFunction expects A_t *trialptr , but you pass volatile A_t* , it's obviously compile error.

And finally:

function trialFunction(volatile A_t *trialptr)
{
     int *p = trialptr->a2;
}

It's OK to compile, because a2 's type is int* .

My preferred placement is typically in the pointer declaration. That way, all of the registers in the struct will be treated, by the compiler, as volatile and yet it is possible to have other (eg RAM-based shadows) instances of said struct that are not volatile because they are not actually hardware registers underneath.

I therefore advise you to use:

typedef volatile struct

Have a nice day

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM