16-12-2013, 09:40 PM
I believe that this rule uses the definition of "constant expression" from the ISO C99 standard Section 6.6. The constraints on constant expressions prohibit the following operators: assignment, increment, decrement, function-call and comma. There's an exception for such operators appearing in an expression that isn't evaluated.
The constraints therefore seem to permit access to objects within constant expressions. However, the Semantics section goes on to list the permitted operands for integer constant expressions. That list does not include objects as being allowed in integer constant expressions so I think that would suggest that "c+1u" where "c" is an object with a const-qualified type isn't a constant expression. Further, using "c+1u" in a context where a constant expression is required gives rise to undefined behaviour because it violates a "shall" or "shall not" appearing outside a Constraints section. See Annex J.2, which states the undefined behaviour w.r.t. constant expressions for confirmation.
Just to complicate matters, I see that the C99 standard Section 6.6 para 10 says that an implementation may accept other forms of constant expression. An implementation that does so would, as as with any extension, have to guarantee that the behaviour of a strictly conforming program isn't changed. Since no strictly conforming program would, by definition, be relying on undefined behaviour it's safe for an extensions to accept objects with const-qualified types in a constant expression. I think this explains why some implementations accept a less strict form of constant expression than is specified in the standard and why it can vary between implementations.
So far as the rule is concerned, I don't know what the MISRA C Working Group guidance would be. I suspect it may be best to stick with the rule as worded, namely that the expression must satisfy the constraints in order for the rule to apply, regardless of whether the implementation is less strict. At least that means that the rule doesn't apply to "c+1u" in either of these sequences:
and
I'd be interested to know that official view on this, as well as the several other unanswered posts. There hasn't been much by way of official responses in the last few months. Any chance of some comments from MISRA?
The constraints therefore seem to permit access to objects within constant expressions. However, the Semantics section goes on to list the permitted operands for integer constant expressions. That list does not include objects as being allowed in integer constant expressions so I think that would suggest that "c+1u" where "c" is an object with a const-qualified type isn't a constant expression. Further, using "c+1u" in a context where a constant expression is required gives rise to undefined behaviour because it violates a "shall" or "shall not" appearing outside a Constraints section. See Annex J.2, which states the undefined behaviour w.r.t. constant expressions for confirmation.
Just to complicate matters, I see that the C99 standard Section 6.6 para 10 says that an implementation may accept other forms of constant expression. An implementation that does so would, as as with any extension, have to guarantee that the behaviour of a strictly conforming program isn't changed. Since no strictly conforming program would, by definition, be relying on undefined behaviour it's safe for an extensions to accept objects with const-qualified types in a constant expression. I think this explains why some implementations accept a less strict form of constant expression than is specified in the standard and why it can vary between implementations.
So far as the rule is concerned, I don't know what the MISRA C Working Group guidance would be. I suspect it may be best to stick with the rule as worded, namely that the expression must satisfy the constraints in order for the rule to apply, regardless of whether the implementation is less strict. At least that means that the rule doesn't apply to "c+1u" in either of these sequences:
Code:
const uint16_t c = 0xffffu;
uint16_t y = c + 1u;
Code:
uint16_t c = 0xffffu;
uint16_t y = c + 1u;
I'd be interested to know that official view on this, as well as the several other unanswered posts. There hasn't been much by way of official responses in the last few months. Any chance of some comments from MISRA?
<t></t>