-3

I am trying to return a string from a array with 4 hexadecimal values. I have a huge list of hex arrays and need to use it in multiple functions. That's why I want to create a function of comparing the hex arrays and return a string.

int comparehex(byte hex[]){
  char * buffer = new char [16];

  byte hex1[4] = {0x4C, 0x79, 0x52, 0xA8};
  byte hex2[4] = {0xC5, 0x86, 0xA4, 0xB5};

  for (byte i = 0; i <=3; i++){
    if (hex1[i] != hex[i]){
      break;
    }
    if (i == 3){
      return "string";
    }
  }
  return false;
}

The code that I wrote won't even compile:

main.cpp: In function ‘int comparehex()’:
main.cpp:46:14: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
   46 |       return "string";
      |              ^~~~~~~~
      |              |
      |              const char*

How can I return a string?

  • 5
    Change `int comparehex(byte hex[]){` to `std::string comparehex(byte hex[]){` to return a string. Although you will have to change `return false;` to something else as false is not a std::string. – drescherjm Dec 16 '21 at 17:38
  • 3
    You'd start by declaring a function with the correct return type. Though in your case that is already a problem, since one code path returns `"string"` while another returns `false` - two different types – UnholySheep Dec 16 '21 at 17:38
  • I'm curious: is this Arduino code? I see you're using `byte`. – Gabriel Staples Dec 16 '21 at 17:41
  • Also, please add a comment header to the function to describe what you expect the function to do, so we can better help you in our answers. – Gabriel Staples Dec 16 '21 at 17:41
  • 1
    To clarify, if need to convey more information in the return value that can be encapsulated in a built-in type, define your own type and return that instead. Maybe that type can have a member that is a `std::string`, bool, .... – Mansoor Dec 16 '21 at 17:45
  • 1
    @GabrielStaples [std::byte](https://en.cppreference.com/w/cpp/types/byte). – 273K Dec 16 '21 at 17:49
  • 3
    why function name is `comparehex`? What this function should do? If not comparing hex then change name. It is strange that result of comparing should be a string (`int` make more sence). – Marek R Dec 16 '21 at 17:50

3 Answers3

1

Function Declaration general rule:

return_type function_name( parameter list );

in your case:

int comparehex(byte hex[])

return_type : int
function_name : comparehex.
parameters : byte array.

As per declaration, function is supposed to return int. but as per your code

      return "string"; // returns a STRING
    }
  }
  return false; // return a boolean

To return a string output, declare the return_type as std::string as in. to do that you need to include "string" library.

#include <string>

std::string comparehex(byte hex[])

Although the return of boolean is cast to int (implicit type conversion).it is not a good practice and is considered unsafe. refer to Implicit type conversion in C for more details.

bscharan
  • 137
  • 1
  • 13
  • "implicit type conversion" -- yes. "typecast" no; there are no casts in this code. A cast is something you write in your source code to tell the compiler to do a conversion. +1. – Pete Becker Dec 16 '21 at 18:18
1

Here is an example of returning const char* with nullptr as a special type of "sentinel value" to mean "false":

There are a lot of potential things to address here, and we don't really understand your purpose of the function or use-case, but let me just address your immediate code and one viable solution.

There are many potential ways to handle this. Again, here is just one. But, I have to make some assumptions to even answer. Let's assume that:

  1. Your function needs to return either a string literal OR false (or something equivalent to represent this).
    1. This means you will NOT be generating a string at run-time inside the function. You will ONLY return a string literal (meaning: a compile-time-constant string with double quotes around it like this: "some string literal") which is set in your source code and fixed at compile-time. Otherwise, my example may not meet your needs, and would need some changes.
  2. You will never need to return true. Rather, the existence of a string indicates true as well.

In this case:

// 1. Change this:
int comparehex(byte hex[])
// to this:
const char* comparehex(byte hex[])

// 2. change this:
return false;
// to this:
return nullptr;

// now this line is fine too:
return "string";

Now, the function returns either nullptr to indicate false, OR a string literal such as "string".

You'd simply check to see if "false" was intended by checking like this:

const char* str = comparehex(some_hex_array);
if (str == nullptr)
{
  // `comparehex()` essentially returned `false`, so do what you need to do here
}
else
{
  // str was set to some string, so use its value (ex: print it)
  printf("%s\n", str);
}

Final notes:

  1. Again, if you're generating a new string inside the function at run-time, rather than returning a string literal set at compile-time, the above 2 changes are not sufficient.
  2. Also note that the above code is rather "C-like". It is perfectly valid C++, but only one of many ways to handle the above scenario.
  3. And lastly, nullptr here can be considered a type of "sentinel value", which means simply that it is a special value of your return type (const char*) to indicate a special meaning: false in this case. And therefore, by extension, this sentinel value of nullptr also possesses the special meaning of whatever you intend "false" to mean.

Related

  1. For another generic example of returning const char*, see my const char * reset_cause_get_name(reset_cause_t reset_cause) function in my answer in C here: STM32 how to get last reset status. I don't return NULL (the C analogue to C++'s nullptr) for cases where no match is found, but I could. (In my example I set it to "TBD" instead of NULL).
  2. See also: What exactly is nullptr?
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
0

In your case, you could add another parameter for passing by reference:

int comparehex(byte hex[], std::string& result_string);

In your code, before returning, set the result_string parameter to the string you want to return.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • For input params, const reference is ok, but for output params, I always consider it best practice to use non-const pointers, so that it is obvious when you call the function that the function may modify the parameter because you see the address symbol (`&`) in front of the param as you make the function call. In other words, I'd recommend a function prototype of `int comparehex(byte hex[], std::string* result_string);` over `int comparehex(byte hex[], std::string& result_string);`. – Gabriel Staples Dec 17 '21 at 17:00
  • The problem with pointers is that they can point to *anywhere*, including being `nullptr` or pointing to undefined address space (or maybe worse, pointing to some invalid data). With references, the referrent must exist and therefore you don't need to validate it (the compiler has done this for you). – Thomas Matthews Dec 17 '21 at 18:39
  • That's true. I still prefer the ptr, but it's a tradeoff, as are most decisions in coding. – Gabriel Staples Dec 17 '21 at 18:52