-3

I am facing scenario where rule 9.1 getting violated. I want to read an auto variable(having garbage value while declaring) before initialization and to assign null if it is not null. If it is null, then with different value. Sample code:

{ 
    int8_t reg_num; 
    uint64_t var1[NUM]; 
    for (reg_num = 0; reg_num < NUM; reg_num++) {
        if (var1[reg_num] != VAR_NULL) { 
            var1 [reg_num] = VAR_NULL; 
        } else { 
            var1[reg_num] = func1(); 
        } 
    } 
}

Violation is for the line if (var1[reg_num] != VAR_NULL) where var1[reg_num] is reading before initialization.

Is there any way to write the same code without violating 9.1

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Salim
  • 373
  • 1
  • 9
  • 19
  • 1
    NO, the warning is correct, fix your code/ logic. – Sourav Ghosh Dec 19 '17 at 04:48
  • 2
    I wonder why would you do that? Uninitialized variables may have any value, so, the probability of reaching the if statement `if(var1[reg_num] != VAR_NULL` is near zero. What is specified in `VAR_NULL`, though? – campescassiano Dec 19 '17 at 04:54
  • Ya. tool is showing the violation correctly and the logic is correct. But how to change the code – Salim Dec 19 '17 at 04:55
  • This is to check the garbage value is 0 or not. VAR_NULL value is 0. Program requires this condition' – Salim Dec 19 '17 at 04:56
  • 1
    What you are trying to do is madness for MISRA point-of-view, but, have you tried to create a `uint64_t *var1` pointer instead, dynamic allocate the array you want, then iterate over it checking in the similar way you are doing? I don't have the MISRA C checker here to validate, but, it could work to "cheat" it. – campescassiano Dec 19 '17 at 05:04
  • A good way to write the loop is: `for (reg_num = 0; reg_num < NUM; reg_num++) { var1[reg_num] = func1(); }`. It sets each element to the value returned by `func1()`. If you don't do that, you must initialize the array. That's easy if you want zeros: `uint64_t var1[NUM] = { 0 };` — but then everything will be zero, so the function will be called. As written, you have no way (guaranteed by the language) to predict what's going to happen. You could set the array to a different value (in various ways). What you can't do (the MISRA checker is right complaining about it) is use uninitialized data. – Jonathan Leffler Dec 19 '17 at 05:04
  • 1
    @phyloflash: other MISRA rules say "no use of dynamic memory allocation (at least, not once the program is out of the startup phase)". – Jonathan Leffler Dec 19 '17 at 05:05
  • @Salim: Alright, if "Program requires this condition", and also requires MISRA compliance, that sounds like an absurdity that only a professor could come up with. What's the rest of the story? – Mark Benningfield Dec 19 '17 at 08:15
  • 1
    While reading uninitialized values is bad, answers here suggest that it is *undefined behaviour*. I am not sure about that in this specific case, so I asked [question about it](https://stackoverflow.com/q/47884469/694733). – user694733 Dec 19 '17 at 10:10
  • This question is a duplicate, since the MISRA-C aspect here is simply "don't do it". – Lundin Dec 19 '17 at 10:15

3 Answers3

2

The tool is correct to report the error.

Quoting C11, chapter §6.7.9

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. [....]

To avoid this, you can initialize the array to some value, say, 0 while defining. This way, you have a predictable value present in each of the elements.

To add, it makes no sense of the logic stated above (i.e., checking a value of an uninitilized variable, in general), at best, it will invoke undefined behavior. Don't do it.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Actually I want to initialize the elements according to the above condition – Salim Dec 19 '17 at 04:58
  • @Salim what's the point? – Sourav Ghosh Dec 19 '17 at 04:59
  • I want to initialize elements in array as null if it is not null. If it is null, then with different value. – Salim Dec 19 '17 at 05:05
  • 5
    @Salim Why? That code is undefined behavior. If you need some kind of randomness here, use random number generator. – hyde Dec 19 '17 at 05:09
  • Incorrect part quoted. The relevant part is C11 6.3.2.1. See https://stackoverflow.com/a/40674888/584518. – Lundin Dec 19 '17 at 10:13
  • @Lundin Well, It was in regards to having uninitialized value, but I can add the part you mentioned, too. – Sourav Ghosh Dec 19 '17 at 10:21
  • 1
    @SouravGhosh Actually, array indexing counts as taking the address so I wasn't correct about 6.3.2.1 being relevant in the specific case. However, the specific case does _not_ invoke UB, but merely unspecified behavior, because it is a stdint.h type. See this answer to a follow-up question: https://stackoverflow.com/a/47884826/584518 – Lundin Dec 19 '17 at 10:33
1

All you have to do is initialize your variables. This is practically rule #2 when learning C -- very, very basic material. The MISRA rule is just telling you to follow the basic rules in C.

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#define NUM 10

/* assumes your VAR_NULL is zero */
#define VAR_NULL 0LLU

uint64_t func1(void)
{
  return 3LLU;
}

int main(void)
{
  int8_t reg_num = 0;
  uint64_t var1[NUM] = { 0LLU };
  for (; reg_num < NUM; reg_num++)
  {
    var1[reg_num] = func1();
  }
  getchar();
  return 0;
}

With the initialized variable, the array initialization code is simplified as a matter of course. In case you missed it, the point is to initialize variables when you define them.

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31
-1

Although some of MISRA's rules are bordering on whimsical idiosyncratic dogmatic pedantry, this one about reading uninitialised variables is directly lifted from the language itself: with a few exceptions the behaviour on reading an uninitialised variable is undefined.

Don't do it: MISRA or no MISRA.

In your case you can write uint64_t var1[NUM] = {0};

Bathsheba
  • 231,907
  • 34
  • 361
  • 483