The code below gives me a warning for the line "}while(!OK && Retries < 3);" in the 'SendRemote' function and where it says 'OK' is defined is in the next function - 'ReceiveRemote'
What is going on here, please?
Warning Message:
C:\Users\Jim\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.2\cores\arduino\main.cpp: In function 'main':
C:\Users\Jim\Desktop\sketch_feb23a\sketch_feb23a.ino:33:16: warning: 'OK' may be used uninitialized in this function [-Wmaybe-uninitialized]
** }while(!OK && Retries < 3);**
** ^**
C:\Users\Jim\Desktop\sketch_feb23a\sketch_feb23a.ino:40:8: note: 'OK' was declared here
** bool OK;**
** ^**
char ReadBuffer[20];
void setup() {
// put your setup code here, to run once:
bool OK;
char M[] = "Hello";
Serial.begin(9600);
OK = SendRemote('a', M);
if(OK)
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
}
bool SendRemote(char MessageType, char *Msg)
{
bool OK;
uint8_t Retries;
OK = HC12BuildMessage(MessageType, Msg);
if(OK)
{
Retries = 0;
do
{
Serial.print(Msg);
OK = ReceiveRemote();
Retries++;
}while(!OK && Retries < 3);
}
return OK;
}
bool ReceiveRemote(void)
{
bool OK;
uint8_t CharTimeout = 20;
uint16_t RecvTimeout = 2000;
char InChar;
uint32_t CharTimer;
uint32_t MsgTimer;
ReadBuffer[0] = 0; // Clear receive buffer
MsgTimer = millis() + RecvTimeout;
// Wait for start character
do
{
InChar = Serial.read();
}while(InChar != '1' && millis() < MsgTimer);
if(InChar == '1')
{
strcat_c(ReadBuffer, InChar);
do
{
CharTimer = millis() + CharTimeout;
do
{
InChar = Serial.read();
if(InChar != -1)
{
if(strlen(ReadBuffer) < 260)
{
strcat_c(ReadBuffer, InChar);
}
else
{
OK = RandomBool();
}
}
}while(InChar == -1 && millis()<CharTimer);
}while(InChar != -1);
}
else
OK = false;
return OK;
}
bool RandomBool(void)
{
bool OK;
OK = random(0, 2) > 0;
return OK;
}
bool HC12BuildMessage(char C, char *P)
{
strcat_c(ReadBuffer, C);
strcat(ReadBuffer, P);
return RandomBool();
}
void strcat_c (char *str, char c)
{
for (; *str; str++); // note the terminating semicolon here.
*str++ = c;
*str++ = 0;
}
'OK' is uininitialised when declared but then receives the return value of a function.
bool OK;
uint8_t Retries;
OK = HC12BuildMessage(MessageType, Msg);
It compiles here with no errors.
hmm it is far from transparant but
OK = ReceiveRemote();
before the condition is checked, but within that function OK, may be undefined, it took some time to verify
if(InChar == '1')
{
strcat_c(ReadBuffer, InChar);
do
{
CharTimer = millis() + CharTimeout;
do
{
InChar = Serial.read();
if(InChar != -1)
{
if(strlen(ReadBuffer) < 260)
{
strcat_c(ReadBuffer, InChar);
}
else
{
OK = RandomBool(); // OK is assigned here, but there is no guarantee that this part of the code is
// executed.
}
}
}while(InChar == -1 && millis()<CharTimer);
}while(InChar != -1);
}
else // the else to the first condition (InChar == '1')
OK = false;
return OK;
}
So the compiler is correct ! with all the random assignments to 'OK' from RandomBool() anyway, it may as well be left as it is though.
This is a very much cut down version of my full program. 'RandomBool' is there to replace other functions which return a bool value without including the whole mass of code.
This version will not do anything useful but it shows the same warning message as the full program.
AlbertHall:
This version will not do anything useful but it shows the same warning message as the full program.
You can apply the analysis of the error to the full program, then.
Wow, that's strange. I THINK I see what it is talking about:
In ReceiveRemote() the local 'OK' variable is uninitialized and only set in conditionals:
if (strlen(ReadBuffer) < 260)
{
strcat_c(ReadBuffer, InChar);
}
else
{
OK = RandomBool();
}
and
}
else
OK = false;
return OK;
That possibly-uninitialized value is returned to SendRemote() where it is stored in the local 'OK' and used in a conditional. Technically, the 'OK' in SendRemote() IS initialized, but it is initialized to a value that may NOT be initialized.
In ReceiveRemote() you should initialize OK.
johnwasser:
Wow, that's strange. I THINK I see what it is talking about:
That possibly-uninitialized value is returned to SendRemote() where it is stored in the local 'OK' and used in a conditional. Technically, the 'OK' in SendRemote() IS initialized, but it is initialized to a value that may NOT be initialized.
In ReceiveRemote() you should initialize OK.
As i said, but RandomBool() returns a random value, which is what an uninitialized value is as well.
johnwasser:
Wow, that's strange. I THINK I see what it is talking about:
In ReceiveRemote() you should initialize OK.
Yes, thanks, and that fixes the warning in the BIG program too.
Your error message is somewhat confusing, because you have defined OK as a global variable, and as separate local variables within several functions. If you change the local variable inside sendRemote() to srOK, the error message them becomes:
/home/jdbarney/.arduino15/packages/arduino/hardware/avr/1.8.2/cores/arduino/main.cpp: In function 'main':
/home/jdbarney/Arduino/sketch_feb18a/sketch_feb18a.ino:34:20: warning: 'OK' may be used uninitialized in this function [-Wmaybe-uninitialized]
} while (!srOK && Retries < 3);
^
/home/jdbarney/Arduino/sketch_feb18a/sketch_feb18a.ino:41:8: note: 'OK' was declared here
bool OK;
^
Which seems to not make much sense, but as was mentioned above the problem is in the ReceiveRemote() function where OK is set inside several conditional statements that the compiler cannot determine will be guaranteed to be executed.
Deva_Rishi:
RandomBool() returns a random value, which is what an uninitialized value is as well.
Not true. An uninitialized bool might always be true, or it might always be false, or it might depend on the calling context. I don't think it would pass any statistical tests for randomness. For example:
false true
false false
false true
false true
false false
false false
false true
false true
false false
false false
false true
false false
false true
false true
false true
false true
false true
false true
false false
false true
false false
false true
false true
false false
void setup()
{
Serial.begin(115200);
}
void loop()
{
bool uninitializedBool;
bool randomBool = RandomBool();
Serial.print(uninitializedBool ? "true" : "false");
Serial.print('\t');
Serial.println(randomBool ? "true" : "false");
delay(500);
}
bool RandomBool(void)
{
bool OK;
OK = random(0, 2) > 0;
return OK;
}
johnwasser:
Not true. An uninitialized bool might always be true, or it might always be false, or it might depend on the calling context.
What i mean to say is that uninitialized (possibly..) does actually have any possible value, but not an impossible value. the truth table does not look like
both true
both false
and we don't know what is going to be upfront, it is going to be a surprise, which is what i want out of a random value. Mathematically speaking it is 'not a random value' since a random mathematical value gets generated using a random generating algorithm which as result of mathematical operations generate numbers that seem random and that pass a statistical test. Not only that, but since the variable is local it may be in memory at a location that is also home to a different variable in some other function (maybe i haven't actually checked to code to see if that is possible in this case, but it is in general.) or the value it had last time it existed in the same function, when it did get assigned a (mathematically random) value. I am still a little puzzled wht the program is supposed to do and what these random value are for, but OK, that is a different matter.
So it is a 'random value' in the eyes of a child, like the flip of a coin.