0

I am new to C++ and converting my code that I have written in C into C++.

here is the struct code.

typedef struct {
uint16_t index; /**< PDO entry index. */
uint8_t subindex; /**< PDO entry subindex. */
uint8_t bit_length; /**< Size of the PDO entry in bit. */
} ec_pdo_entry_info_t;

and here is the declaration of struct in C-lang.

ec_pdo_entry_info_t slave_0_pdo_entries[] =
    {
            { 0x6040, 0x00, 16 },    //    0
            { 0x607a, 0x00, 32 },    //    2
            { 0x60b0, 0x00, 32 },    //    6
            { 0x60b1, 0x00, 32 },    //    10
            { 0x60b2, 0x00, 16 },    //    14
            { 0x6060, 0x00, 8 },    //    16
            { 0x2078, 0x01, 16 },    //    17
            { 0x60b8, 0x00, 16 },    //    19
            { 0x6041, 0x00, 16 },    //    21
            { 0x6064, 0x00, 32 },    //    23
            { 0x606c, 0x00, 32 },    //    27
            { 0x6077, 0x00, 16 },
            { 0x6061, 0x00, 8 },
            { 0x2071, 0x01, 16 },
            { 0x60b9, 0x00, 16 },
            { 0x60ba, 0x00, 32 },
            { 0x60bb, 0x00, 32 },
    };

I have made a class in which I have declared a variable like below,

ec_pdo_entry_info_t slave_0_pdo_entries[];

Now in a constructor I want to declare slave_0_pdo_entries[] variable as I have done in c-lang. Could you please help guide me how can I do this?

Etherlabinterface::Etherlabinterface()
{
master=NULL;
domain0=NULL;
sc_epos3=NULL;
domain0_output=NULL;


slave_0_pdo_entries[]=
        {
                { 0x6040, 0x00, 16 },    //    0
                { 0x607a, 0x00, 32 },    //    2
                { 0x60b0, 0x00, 32 },    //    6
                { 0x60b1, 0x00, 32 },    //    10
                { 0x60b2, 0x00, 16 },    //    14
                { 0x6060, 0x00, 8 },    //    16
                { 0x2078, 0x01, 16 },    //    17
                { 0x60b8, 0x00, 16 },    //    19
                { 0x6041, 0x00, 16 },    //    21
                { 0x6064, 0x00, 32 },    //    23
                { 0x606c, 0x00, 32 },    //    27
                { 0x6077, 0x00, 16 },
                { 0x6061, 0x00, 8 },
                { 0x2071, 0x01, 16 },
                { 0x60b9, 0x00, 16 },
                { 0x60ba, 0x00, 32 },
                { 0x60bb, 0x00, 32 }
        };

constructor to initialize struct. Answer I have accepted is working but I am facing new problem, this array will be used by another array but when I but this thing in that it is giving me different error.

after initializing array as accepted answer, I neeed to initialize another array, see below,

ec_pdo_info_t slave_0_pdos[] = {
{0x1605, 7, slave_0_pdo_entries + 0}, 
{0x1a02, 5, slave_0_pdo_entries + 7}, 
}

In above array it is giving error + operator is not valid..

after above array I need to initialize another array like below,

ec_sync_info_t slave_0_syncs[] = {
{0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
{1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
{2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE}};

It is showing me same error..kindly guide me.. Thank you.

7
  • in which constructor? Commented Jan 2, 2014 at 11:17
  • If slave_0_pdo_entries was static in your class then you should be able to initialize it like in C. Commented Jan 2, 2014 at 11:20
  • no it is not static in my class, Commented Jan 2, 2014 at 11:26
  • You must specify the size of your array if you do not initialize it right away Commented Jan 2, 2014 at 11:28
  • @itwasntpete: The one that is currently implicit. Commented Jan 2, 2014 at 11:30

3 Answers 3

3

Your array declaration has no size, how can the compiler know how many elements of that type to allocate when instantiating an object of your class? It cannot.

Also, as a rule of thumb in C++ always try to use std::vector or std::array instead of C-style arrays.

Since your data there appears to be static and const you can do:

class the_class {
private:
    static constexpr std::array<ec_pdo_entry_info_t, 17> slave_0_pdo_entries {{
            { 0x6040, 0x00, 16 },    //    0
            { 0x607a, 0x00, 32 },    //    2
            { 0x60b0, 0x00, 32 },    //    6
            { 0x60b1, 0x00, 32 },    //    10
            { 0x60b2, 0x00, 16 },    //    14
            { 0x6060, 0x00, 8 },    //    16
            { 0x2078, 0x01, 16 },    //    17
            { 0x60b8, 0x00, 16 },    //    19
            { 0x6041, 0x00, 16 },    //    21
            { 0x6064, 0x00, 32 },    //    23
            { 0x606c, 0x00, 32 },    //    27
            { 0x6077, 0x00, 16 },
            { 0x6061, 0x00, 8 },
            { 0x2071, 0x01, 16 },
            { 0x60b9, 0x00, 16 },
            { 0x60ba, 0x00, 32 },
            { 0x60bb, 0x00, 32 }
    }};
    //...
};

And here you can find the working example.

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

9 Comments

This is the correct solution if the data is the same for all instances of the class. If the data in slave_0_pdo_entries is not static, then an initializer list should be used. Refer to en.cppreference.com/w/cpp/language/initializer_list Since C arrays don't support initializer lists, a std::vector or std::array has to be used in that case.
how can I use this method for public?
I am using this technique but when I try to compile code it is giving me below error, Multiple markers at this line - identifier ‘constexpr’ will become a keyword in C++0x [-Wc++0x- compat] - ‘constexpr’ does not name a type - C++0x ‘constexpr’ only available with -std=c++0x or -std=gnu++0x - Symbol 'array' could not be resolved
@nabeel: The error message is pretty clear: you need to pass the flag -std=c++0x (or better -std=c++11) to the compiler in order to enable C++11 features (which this solution uses a lot).
@nabeel and remember to #include<array>.
|
2

What you have done in C is actually quite a special thing. Usually you have to specify a size for all arrays that you allocate, with the one exception that you may omit the array size if you directly initialize it with a braced list as you have done. In this special case, the compiler can deduce the size of the array from the size of the initializer list.

Now, you might ask: Why didn't the compiler throw an error on the declarion of ec_pdo_entry_info_t slave_0_pdo_entries[];?
The answer is, that you have invoked anothe special case: You can use one (and only one) array with unspecified size at the end of a struct/class. But, the compiler won't allocate any memory for it, you would have to allocate enough memory yourself for the object. So, just initializing this array in the constructor is very dangerously wrong.

You have several ways, in which you can fix your problem, the other answers give the different ways to do it: either initialize the variable at the place where it is declared, or use some higher level constructs like std::array or std::vector.

Comments

0

First of all this definition of non-static data member

ec_pdo_entry_info_t slave_0_pdo_entries[];

of the class is incorrect. The array must be a complete type that is its dimension shall be specified.

If you want to use the brace initializer for the array then you should use std::array class instead of the array. For exanoke

std::array<ec_pdo_entry_info_t, 17> slave_0_pdo_entries;

and inside the body of the constructor write

slave_0_pdo_entries =
    {
            ec_pdo_entry_info_t( { 0x6040, 0x00, 16 } ),    //    0
            ec_pdo_entry_info_t( { 0x607a, 0x00, 32 } ),    //    2
            // other initializers
            ec_pdo_entry_info_t( { 0x60bb, 0x00, 32 } ),
    };

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.