MISRA Discussion Forums

Full Version: Making constants in MISRA compliant C++
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am trying to declare a constant for use in fixing the size of several C++ arrays. I have tried 3 options:
1) #'define MaxTracksConst 8

2) const Rhp_int32_t MaxTracksConst(8);

3) enum %s {one, two, three, four, five, six, seven, MaxTracksConst}

but our LDRA MISRA checker finds fault with all of them ( 1. fails 16-2-2, 2. fails 3-1-1 and 3. fails 4-5-2 ).
Am I missing something, or is there an option that will pass MISRA C++ 2008 checks ?

Kind regards
Insane Vent Storm
I've been faced with the same issue and I choosed kinda 3):

public header:
enum SIZES
    MAX_USER_NAME = 64U,
    MAX_GROUP_NAME_ = 32U,
    MAX_USERS = 256U,
// Note: This does not violate any rules, especially not the ODR!

void myFunc()
    char_t userList[ MAX_USERS ][ MAX_USER_NAME ];
    // IMHO this does NOT violate 4-5-2. LDRA is known for some false positives.
    for ( size_t idx = 0U; idx < static_cast( MAX_USERS ); idx++ )
        userList[ idx ][ 0U ] = '\0';

Anybody any idea about this?
Did you know you can compare against PC-LINT for free?
See http://www.gimpel-online.com/OnlineTesting.html.
Be sure to write //lint -indirect(au-misra-cpp-alt.lnt) at the top of your sample code to get MISRA C++ 2008 checks.
From my experience, all these tools either suffer from false positives or missing checks or both.
In your case no violation of 4-5-2 is reported and after reading the rule again i agree.
Also, number 2) is not a violation of 3-1-1 if the constant is in a header file, initialized with a literal and thus can be replaced at compile-time (no storage allocated).
Addendum for 2): of course you need to minimize visibility of the constant ( there is a separate rule for that), e.g. use static const in a class. Again, no storage is allocated unless the address is taken, so no violation of 3-1-1 possible.
The preferred method of declaring constants in C++ is 2, though 3 is acceptable in the specific case of declaring or accessing an array.

Your checker shouldn't report 2 as a violation of the ODR (3-1-1)

In a future version or Technical Corrigendum we ought to consider clarifying that 3-1-1 does not apply to const declarations.

If the const were made static, 2-10-5 may also need modification to allow it as an exception
I see! Actually, FlexeLint does NOT report a deviation on const definitions in header files (I havn't tried this at all because of 3-1-1). And I also agree, this exception should be mentioned in 3-3-1's text and example, too.
Many thanks for your support!
You're welcome
Could I also suggest that when making constants, an exception might also be needed in Rule 0-1-6 (A project shall not contain instances of non-volatile variables being given values that are never subsequently used), eg.:

std::int32_t doIt_const3_neq0(const std::int32_t aVal)
  // Minimize scope to avoid violating Rule 3-4-1
  static const std::int32_t kConst3 = 7;

  return (aVal != 0) ? aVal : (aVal + kConst3);

In the code above, it is possible that kConst3 may be given a value, but that value is never subsequently used (it depends on the branches taken).

The program will not compile if kConst3 is not defined, so it is used by the compiler. If the correct set of branches are taken, it also effects program operation, so it is not dead code.

But, its usage can only be determined based on each individual program execution - some days it may not be used, other days it may be used.

However, the alternative (to avoid breaching rule 0-1-6) seems to be to use literal (magic) values directly in the code, which does not match current programming practice.
Your code shouldn't be getting a violation of 0-1-6. As you say, 0-1-6 worries about "variables being given values that are never subsequently used" - NEVER being the operative word.

Analysis of this function should determine that kConst3 MAY be used, depending upon the value of aVal, so no report is required