Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
13.1 when initializing with address of volatile variable
#1
13.1 indicates that an initializer list shall not contain persistent side effects, and gives an example of initializing with a volatile variable access. I believe there would be general agreement that
Code:
volatile uint16_t v1;

volatile uint16_t *a[1] = {&v1};
does not count as an "access" and is therefore compliant.

What about address of submembers of a volatile aggregate?
Code:
struct foo
{
    uint16_t bar;
};
volatile struct foo baz;
volatile uint16_t *a[1] = {&baz.bar};

Our cross-compiler defines our microconroller's memory mapped registers by address, like so:
Code:
struct foo
{
    uint16_t bar;
};
#define REG1 (*(volatile uint16_t *)0x100)
#define REG2 (*(volatile struct foo *)0x1000)

volatile uint16_t *a[2] = {&REG1, &REG2.bar};
Are either of the members of this initializer list complaint?
<t></t>
#2
All your examples are compliant with rule 13.1. Taking the address of a volatile variable is not a "persistent side effect".

In the &REG1 and &REG2.bar examples, neither the & or * operator are evaluated - see C99 6.5.3.2(3).
For example: &(*(volatile uint16_t *)0x100) is equivalent to (volatile uint16_t *)0x100
Posted by and on behalf of the MISRA C Working Group
#3
misra-c Wrote:All your examples are compliant with rule 13.1. Taking the address of a volatile variable is not a "persistent side effect".

In the &REG1 and &REG2.bar examples, neither the & or * operator are evaluated - see C99 6.5.3.2(3).
For example: &(*(volatile uint16_t *)0x100) is equivalent to (volatile uint16_t *)0x100

I don't see how the exception in C99 6.5.3.2(3) applies in the case of &REG2.bar since the operand of the & operator in this case is the result of the member access operator, not the * or [] operators. Can you please clarify your position and/or rationale for this part of the example?
<t></t>
#4
Yes, you are correct. We had misparsed the macro expansion for &REG2.bar when writing the response.

Our position is that taking the address of REG2.bar is not a volatile access and there is no violation of rule 13.1.

The reason for this is as follows. REG2 expands to an lvalue. According to C99 6.3.2.1(2) an lvalue, appearing as the left operand of the "." operator, is not converted to a value (i.e. there is no memory access). According to C99 6.5.2.3(2), the result of the "." operator is an lvalue. Then according to C99 6.5.3.2(3) the "address of"(&) operator converts its operand to its address and again, no memory access is involved.
Posted by and on behalf of the MISRA C Working Group


Forum Jump:


Users browsing this thread: 2 Guest(s)