13.1 when initializing with address of volatile variable

Moderators: misra-c, david ward

michael.metivier
Posts: 10
Joined: Thu Mar 21, 2013 7:30 pm
Company: Gentex, Corp.

13.1 when initializing with address of volatile variable

Postby michael.metivier » Wed Aug 08, 2018 4:51 am

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: Select all

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: Select all

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: Select all

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?

misra-c
Posts: 535
Joined: Thu Jan 05, 2006 1:11 pm

Re: 13.1 when initializing with address of volatile variable

Postby misra-c » Thu Oct 18, 2018 2:00 pm

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

rgamble
Posts: 12
Joined: Fri Jul 20, 2007 7:54 pm

Re: 13.1 when initializing with address of volatile variable

Postby rgamble » Mon Dec 03, 2018 9:24 pm

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?

misra-c
Posts: 535
Joined: Thu Jan 05, 2006 1:11 pm

Re: 13.1 when initializing with address of volatile variable

Postby misra-c » Fri Dec 14, 2018 3:59 pm

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


Return to “8.13 Side effects”

Who is online

Users browsing this forum: No registered users and 1 guest