Invalid conversion error on NodeMCU/ESP8266 but not on Arduino

Hello all,
I'm fairly new to C++ and Arduino, and I'm finding the char array hill difficult to climb. It's not made any easier when I have code that compiles and runs as expected on an Arduino Mega, but fails to compile on a "Generic ESP8266 Module".

Can anyone offer some insight as to why I either have perfectly valid code that is not compiling (ESP8266), or I have invalid code that IS compiling (Arduino Mega)?

void parse_metar () {
  Serial.println(F("[PARSING]"));

  // If no metar was returned, print and then get out since there's nothing to parse
  if (strstr(metar, "METAR")) {
    Serial.println(metar);
    return;
  }

  char *ptr = NULL;   // pointer for space-separated chunk of metar data
  char *visibility = 0;     // whole number holder for visibility that includes a fraction (eg. 2 1/2)
  ptr = strtok(metar, " ");
  while (ptr != NULL) {
    if (strstr(ptr, "RMK")) {
      // we can bail here
      break;
    }
    if (strlen(ptr) == 1 && strspn(ptr, "1234567890") == 1) {
      // Fractional visibility so hold on to the whole number
      visibility = ptr;
    } else if (strrchr(ptr, 'SM')-ptr+1 == strlen(ptr)) {
      Serial.print("Visibility: "); 
      if (atoi(visibility) > 0) {
        // Need to recombine the whole number portion of the visibility data (eg. 2 1/2)
        Serial.print(visibility); Serial.print(" "); Serial.println(ptr);
        strcat(visibility, *ptr);  // <<<< ERROR REFERS TO THIS LINE
        check_visibility(*visibility);
       } else {
        check_visibility(*ptr);
      }
    } else if (strstr(ptr, "BKN") || strstr(ptr, "OVC")) {
      Serial.print("Cloud Layer: "); Serial.println(ptr);
        check_ceiling(*ptr);
    }
    ptr = strtok(NULL, " ");
  }
}

The error I get is:
char *strcat (char __restrict, const char *__restrict);
| ^~~~~~~~~~~~
invalid conversion from 'char' to 'const char
' [-fpermissive]

If the error is accurate, how/why does compilation succeed on a different device?

Just taking a stab, I removed the * from the second argument and it compiles, but it crashes the ESP when run.

I am apparently too thick to comprehend this business of char arrays so any help is appreciated.

strcat() takes two pointers, 'visibility' is a pointer. 'ptr' is a pointer so '*ptr' is a char, not a char *

Thanks for your reply! I understand enough of it to see what caused the issue, but I'll have to continue reading about chars and pointers to get a better handle on what they actually mean.

Any idea why it would compile when using the Arduino, though? Perhaps some kind of background "mind-reading"?

And FWIW, the stack crash I was getting after removing the * from ptr was resolved by removing the atoi(visibility) a few lines above, and just checking the value without atoi.

Thanks again. I was really stuck there.

I was also having the same issue. Thanks for sharing these information. It might be helpful to me?

That is because you never set visibility to point to anything. If the 'if' statement is true, you set visibility = ptr, but if it is false, you never set visibility and then pass that null pointer to atoi() - not good. Pointers have to point to some valid memory.

So this line:

char *visibility = 0;

doesn't count, I guess. Is that because that line sets the pointer to an invalid address?

Yes. That lines says visibility is pointing at nothing (nullptr). If you wanted to point to valid memory

char buffer[10];
char *ptr = buffer;

and then if you wrote to the memory location referred to by ptr, it would write into buffer.

Sounds like you might need a bit more reading on C/C++ pointers. We all had to do it at some point.

Got it. It is starting to make sense but you are right that I need to do more reading. Thanks for your help!

strrchr(ptr, 'SM')

What is 'SM' between single quotes ?
Is that a single character or a zero-terminated string ?

'visibility' is a NULL pointer. The ESP8266 can detect the access error, the ATmega can't.