0

I have the following definitions:

struct Display_font_char 
{
    unsigned char * data;
    int originX;
    int originY;
    unsigned int width;
    unsigned int height;
    unsigned int delta;
};

struct Display_font 
{
    Display_font_char * chars;
    unsigned char rangeStart;
    unsigned char rangeEnd;
};

How can I initialize it inplace? I'm trying:

const Display_font font = 
{
    {
        {
            { 1, 2, 3 },
            1,
            2,
            3u,
            4u,
            5u
        }
    },
    1u,
    2u
}

However, I'm getting an error: "Cannot use value of type int to initialize field of type Display_font_char *"

6
  • chars is a pointer, you cannot initialize it with a Display_font_char value. Same goes for data. Commented Feb 23, 2022 at 17:44
  • 2
    Display_font_char * chars; should be std::vector<Display_font_char> chars; Commented Feb 23, 2022 at 17:45
  • @NathanOliver, this is embedded environment and I'd avoid std::vector if I could. Can I? Commented Feb 23, 2022 at 17:45
  • @Quimby, this is meant to be an array of Display_font_chars. Commented Feb 23, 2022 at 17:47
  • You basically have two options. First, you can switch to using a raw array or std::array for chars (and data in Display_font_char). Second, you keep a pointer and use new, or use a vector which manages that for you. Commented Feb 23, 2022 at 17:47

2 Answers 2

1

You cannot initialise a pointer with a braced init list of multiple values.

Here is an example of how you could initialise an instance of the class:

unsigned char uc[] = { 1, 2, 3 };
Display_font_char fc {
    uc,
    1,
    2,
    3u,
    4u,
    5u,
};
const Display_font font = 
{
    &fc,
    1u,
    2u,
};

As a sidenote, if you were to switch to C, then you could use compound literals:

const struct Display_font font = 
{
    &(struct Display_font_char){
        (unsigned char []){ 1, 2, 3 },
        1,
        2,
        3u,
        4u,
        5u
    },
    1u,
    2u
};

But alas, compound literals don't exist in C++.

Sign up to request clarification or add additional context in comments.

Comments

1

In order to initialize your pointers, you have to create the pointed structures first, for example using new.

Notice that, if you want to treat Display_font.chars and Display_font_char.data as arrays, you should save their sizes (e.g. through a size_t data_size member).

In the example below I create the arrays with new[] and I delete them later on with delete[].

[Demo]

#include <iostream>  // cout
#include <ostream>

struct Display_font_char 
{
    unsigned char* data;
    size_t data_size;
    int originX;
    int originY;
    unsigned int width;
    unsigned int height;
    unsigned int delta;
};
std::ostream& operator<<(std::ostream& os, const Display_font_char& f)
{
    os << "\tdata = [";
    for (size_t i{0}; i < f.data_size; ++i)
    {
        os << ((i == 0) ? "" : ", ") << static_cast<int>(f.data[i]);
    }
    os << "]\n";
    os << "\toriginX = " << f.originX << "\n";
    os << "\toriginY = " << f.originY << "\n";
    os << "\twidth = " << f.width << "\n";
    os << "\theight = " << f.height << "\n";
    os << "\tdelta = " << f.delta << "\n";
    return os;
}

struct Display_font 
{
    Display_font_char* chars;
    size_t chars_size;
    unsigned char rangeStart;
    unsigned char rangeEnd;
};
std::ostream& operator<<(std::ostream& os, const Display_font& f)
{
    os << "chars = [\n";
    for (size_t i{0}; i < f.chars_size; ++i)
    {
        os << ((i == 0) ? "" : ", ") << f.chars[i];
    }
    os << "]\n";
    os << "rangeStart = " << static_cast<int>(f.rangeStart) << "\n";
    os << "rangeEnd = " << static_cast<int>(f.rangeEnd) << "\n";
    return os;
}

int main()
{
    const Display_font font = {
        new Display_font_char[1]{
            new unsigned char[4]{1, 2, 3},
            3,  // data size
            1, 2,
            3u, 4u, 5u
        },
        1,  // chars size
        1, 2
    };
    std::cout << font;
    delete[] font.chars[0].data;
    delete[] font.chars;
}

This other version uses std::vector instead of Display_font_char* and unsigned char*, so you don't have to do care about memory allocations/deallocations.

[Demo]

#include <iostream>  // cout
#include <ostream>
#include <vector>

struct Display_font_char
{
    std::vector<unsigned char> data;
    int originX;
    int originY;
    unsigned int width;
    unsigned int height;
    unsigned int delta;
};
std::ostream& operator<<(std::ostream& os, const Display_font_char& f)
{
    os << "\tdata = [";
    bool first{true};
    for (auto& d : f.data)
    {
        os << (first ? "" : ", ") << static_cast<int>(d);
        first = false;
    }
    os << "]\n";
    os << "\toriginX = " << f.originX << "\n";
    os << "\toriginY = " << f.originY << "\n";
    os << "\twidth = " << f.width << "\n";
    os << "\theight = " << f.height << "\n";
    os << "\tdelta = " << f.delta << "\n";
    return os;
}

struct Display_font 
{
    std::vector<Display_font_char> chars;
    unsigned char rangeStart;
    unsigned char rangeEnd;

};
std::ostream& operator<<(std::ostream& os, const Display_font& f)
{
    os << "chars = [\n";
    bool first{true};
    for (auto& c : f.chars)
    {
        os << (first ? "" : ", ") << c;
        first = false;
    }
    os << "]\n";
    os << "trangeStart = " << static_cast<int>(f.rangeStart) << "\n";
    os << "rangeEnd = " << static_cast<int>(f.rangeEnd) << "\n";
    return os;
}

int main()
{
    const Display_font font{
        { { {1, 2, 3}, 1, 2, 3u, 4u, 5u } },
        1,
        2
    };
    std::cout << font;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.