Why a Serial.print can interfere the logic of a function?

So, here is a function in my program:

int CheckSameProduct(byte data[]){
  int checked;
  for(int i=0;i<20;i++)
  {
    for(int j=0;j<14;j++)
    {
      if(data[j]==ID_array[i][j])
      checked++;
    }
    //Serial.print(checked);
    if(checked==14)
    return i;
  }
  return -1;
}

The ID_array is a global 20*14 byte array to store barcode numbers for 20 different commodities, each barcode is 14 bytes long. every digit is ASCII encoded. data is a 14 byte array which contain another barcode. So, feeding in a barcode to this function, it will tell whether and where that barcode is in the barcode database.

While running the program, the functions always return -1, so I added a Serial.print to see where is the problem. Then strange things happened; when Serial.print is added, it works just fine; comment out the Serial.print, it went into problem again.

BTW, this program do use object Serial2, but not Serial; Also, this strange behavior doesn’t rely on actual serial activity, even not adding Serial.begin() in the program will trigger such behavior.

So is there anything wrong with the compiler or there is some kind of hidden error in my program ?

Please post your code.

The ID_array is a global 20*14 byte array to store barcode numbers for 20 different commodities, each barcode is 14 bytes long. every digit is ASCII encoded.

So, you would have an array of strings, if the array was 20 x 15 and each barcode entry was NULL terminated.

While running the program, the functions always return -1, so I added a Serial.print to see where is the problem. Then strange things happened

You are almost certainly stepping on memory you don’t own, somewhere, in the code you didn’t post. Adding the Serial.print() call caused the code to be rearranged, and now you are stepping on memory where the impact is not observed.

Not sure why the Serial.print would make a difference, but your code is not going to work properly regardless. You are looking for checked to have a value of 14, but you never gave checked an initial value (presumably it should start at 0), and you are not resetting the value each time you compare a barcode, so the value of checked will keep an accumulated total of how many matching digits you have found, regardless of how many barcodes those matches are spread across.

Okay it take me a while to figure what is wrong. Seems some kind of bug in the MFRC522 lib caused it to return an abnormally long reading buffer which got it blown.

Apologize for not showing the complete code, but it's over 600 lines and currently I have no access to services like pastebin.

david_2018: and you are not resetting the value each time you compare a barcode.

Thanks, I just assumed "checking" will always be 0 when function being called, but actally not. That's a mistake.

david_2018:
Not sure why the Serial.print would make a difference, but your code is not going to work properly regardless.
You are looking for checked to have a value of 14, but you never gave checked an initial value (presumably it should start at 0), and you are not resetting the value each time you compare a barcode, so the value of checked will keep an accumulated total of how many matching digits you have found, regardless of how many barcodes those matches are spread across.

To summarize what david_2018 and PaulS said, when you declare a variable inside a function, inside a function, you must give it an initial value. Not doing so means it will have the value of whatever is in that address space, and when you increment it, you are not incrementing from Zero, so likely reading from an unknown location of memory. When you add Serial.print, your int changed gets moved to somewhere in memory where the value may just happen to be zero.

int CheckSameProduct(byte data[]){
  int checked = 0;
  for(int i=0;i<20;i++)
  {
    for(int j=0;j<14;j++)
    {
      if(data[j]==ID_array[i][j])
      checked++;
    }
    //Serial.print(checked);
    if(checked==14)
    return i;
  }
  return -1;
}

Not only did you not initialize ‘checked’ but you did not re-initialize it for each check.

If your only two samples are:
ABCD1234EFGH56
1234ABCD5678EF

Then a ‘data’ of 12CDAB3456GHEF will return a match. The first 14 tests will match on CD34GH and the next 14 tests will match on 12AB56EF. That’s a total of 14 matches

int CheckSameProduct(byte data[]){
  int checked;
  for(int i=0; i<20; i++)
  {
    checked = 0;
    for(int j=0; j<14; j++)
    {
      if(data[j] == ID_array[i][j])
        checked++;
      else
        break;  // No need to check the rest after you find a mismatch.
    }
    //Serial.print(checked);
    if(checked==14)
      return i;
  }
  return -1;
}

Of course you already have the counter ‘j’ so you don’t really need ‘checked’. If j gets to 14 then all 14 characters match.