Tikki
Tikki

Reputation: 189

C++ Returning a const unsigned char

So, I've been struggling with this bit. I have a simple function, that is defined as follows:

const unsigned char GetColor(unsigned int x, unsigned int y)
{
    const unsigned char color[3] = {0, 1, 0};
    return color;
} 

Yet, I am not allowed to do this and the compiler returns with the following error:

Error: cannot initialize return object of type 'const unsigned char' with an lvalue of type 'const unsigned char [3]'

Should I convert the array into a pointer to an array, which I should return? If I do this, don't I risk that it may be deleted after going "out of scope" - aka out of the function?

Any help in understanding this problem will be greatly appreciated :)

EDIT: The end goal is to have a function, that can return a color at a pixel location, given an x- and y value. That means that color changes, depending on the value of x- and y. The example above is a simplification.

It should return an const unsigned char array of size 3, with a value in each.

Upvotes: 1

Views: 1143

Answers (1)

The Vee
The Vee

Reputation: 11550

You want to return an array of numbers. You are right that trying to pass some kind of reference to a local variable would create a problem with scope (technically called a dangling pointer / dangling reference), although for different reasons than indicated. (The compiler simply complains about the type disagreement between a single char and an array of chars.)

C++ gives you several safe ways of doing so. For example, you can return an array type:

#include <array>

std::array<unsigned char, 3> GetColor(unsigned int x, unsigned int y)
{
    return {0, 1, 0};
} 

This makes the "three characters" a single variable of a special type that holds three characters, just like a struct { unsigned char a, b, c; }. Or you can make your own type that does something similar.

In the above, you can imagine the "return variable" something invisibly declared by the compiler in a way as if its scope was the statement where you are calling the function. The return statement writes to this variable, rather than to an array local to this function.

Obviously you'd need to change the calling code such that it expects std::array<unsigned char, 3> rather than unsigned char[3], but a) the former version couldn't have worked anyway, so we're speaking of new code rather than trying to change an existing codebase, and b) std::arrays are usually preferred to C-style arrays anyway in new code and it's worth learning to work with them.

Of course, there's always the unsafe way, for example:

unsigned char* GetColor(unsigned int x, unsigned int y)
{
    unsigned char* ret = new unsigned char[3] { 0, 1, 0 };
    return ret;
} 

But then you must not forget to delete[] the returned pointed once you no longer need it.

Upvotes: 7

Related Questions