Please note that the following questions, even though using concrete examples for clarity, are meant to be general; in particular, here we are

*not*asking how the examples should be changed in order to make them compliant with MISRA C++.

**Question 1**:

Given the following context:

Code: Select all

` enum Colours { RED, BLUE, GREEN };`

static const Colours red = RED;

and assuming a deviation from rule 4-5-2, what is the underlying type and cvalue-ness of expressions

Code: Select all

`RED + 1`

Code: Select all

`red + 1`

In section 6.5.0 of MISRA C++ (page 59) it is said:

Additive operators

[...]

The result is a cvalue expression whose underlying type is as defined by the underlying type conversions.

The underlying type conversions (page 57) state that if one of the arguments has

*enum*type then the expression has

*enum*type. Therefore, both expressions should be cvalues having underlying type

*enum Colours*.

However, both expressions are integer constant expressions according to the C++ standard and hence the MISRA C++ rule about the underlying type of constants (page 60) seems to be relevant too:

Constant expressions

The result is not a cvalue expression. The underlying type for a constant expression “e” with a value “v” will have the same signedness as “e”, and a magnitude given by the underlying type of a single integer-literal with the same value as “v”.

According to this rule, we should consider integer literals with the actual values of the expressions (i.e., 1), thereby obtaining non-cvalue expressions having underlying type

*signed char*.

To summarize:

1a) we would like to know if the MISRA rule about constant expressions should be applied

**only**to expressions whose MISRA underlying type (computed as if they were not constants) is "effectively" integral, i.e., different from

*bool*, plain

*char*and

*enum*;

1b) if that is the case (i.e., if

*red + 1*has underlying type

*enum*), then what about its cvalue-ness? Is

*red + 1*a cvalue or not?

**Question 2:**

What is the underlying type of expression

Code: Select all

`1L`

In section 6.5.0 of MISRA C++ (page 58) it is said:

Literals

The underlying type of an integral literal is the smallest fundamental type of the appropriate sign required to store its value. For example, the underlying type of the literal 128 is S16. The result is not a cvalue.

So, the underlying type of

*1L*should be

*signed char*.

Is this really meant to be different from the underlying type computed according to MISRA-C-2004? For instance, in the examples for rule 10.1 (page 43 of MISRA-C-2004) we have the following line:

Code: Select all

` u8a = 5UL; /* not compliant */ `

which is suggesting that the underlying type of

*5UL*is

*unsigned long*. Is the integer literal suffix

*L*relevant only for MISRA C and not for MISRA C++? Once again, this turns out be become a question on the applicability of the rule about constant expressions.

To summarize: we would like to know if the MISRA rule about constant expressions should be applied

**only**to expressions whose MISRA underlying type (computed as if they were not constants) is one of

*signed char, unsigned char, short, unsigned short, int, unsigned int*, thereby disregarding the "big" integer types.

**Question 3:**

Assuming that the answer to the Question 2 above is that the underlying type of

*1UL*is

*unsigned long*, what is the cvalue-ness of

Code: Select all

`-1UL`

If

*1UL*has underlying type

*unsigned long*, then the rule about constants has not been applied. Hence, the only relevant rule is the one about the unary operators. In section 6.5.0 of MISRA C++ (page 58) it is said:

Unary expressions

[...]

- cast-expression

The result is a cvalue expression whose underlying type is that of the cast-expression.

Therefore,

*-1UL*is not a cvalue. Is this meant, or is it the case that

**any**ICE expression (no matter if bool, char, enum or effectively integer) is not a cvalue?

Thanks in advance for any clarification.