1

I have the below code. What am I doing wrong that I can't simple assign the array myBar to the 1st index of foo? Using memcpy works but somehow I don't want to use this approach.

#include <array>
#include <string.h>
#include <stdio.h>
    
using bar = struct bar
{
    int  x;
    char y;
};
    
auto main() -> int
{
    std::array<bar [3], 4> foo;
    
    bar myBar [3] = { { 1, 'a'}, { 2, 'b'}, {3, 'c'} };
    
    //  Compiler error "Invalid array assigment" - comment it to get an executable file.
    foo [0] = myBar; 
    
    // This works and foo [0] has also the correct content
    memcpy( foo [0], myBar, sizeof(myBar) );
        
    for ( auto const & fooBar : foo [0] ) {
        printf( "x=%d - y=%c\n", fooBar.x, fooBar.y );
    }
    
    return 0;
}

Full working MRE:
https://onlinegdb.com/fdMYwcFNus

6
  • 5
    Why mixing std::array with C-array? Commented Oct 1 at 16:29
  • 3
    C arrays are not assignable (you cannot use x = y; with C arrays). But if you use std::array only (which is better anyway, as suggedted above) it will solve your problem as std::arrays are assignable. See demo. Commented Oct 1 at 16:39
  • 1
    Why the using bar = ...? Commented Oct 1 at 16:40
  • A side note: better use C++ I/O instead of printf - std::print from C++23, and std::cout before that). Commented Oct 1 at 16:40
  • Side note: Arrays in C++ were inherited directly from arrays in 1980s C. And arrays in C were designed to solve 1970 computing problems such as RAM measured in K and CPUs with the computing power of a Dorito. Arrays do the job they were designed for very well, but by modern standards they are extremely limited. There's usually a better option like std::array or std::vector, both of which support assignment the way you expect. Commented Oct 1 at 17:18

2 Answers 2

5

foo [0] = myBar; generates a compilation error because C arrays are non-assignable:
If you have 2 C arrays - x and y, you cannot use x = y;.
And in your case foo[0] and myBar are C arrays (not std::arrays).

A solution would be to use std::array consistently (which is recommended anyway), without mixing with C arrays:

#include <array>
#include <iostream>

struct bar {
    int  x;
    char y;
};

auto main() -> int {
    std::array<std::array<bar, 3>, 4> foo;
    std::array<bar, 3> myBar = { bar{ 1, 'a'}, bar{ 2, 'b'}, bar{3, 'c'} };
    foo[0] = myBar;
    for (auto const& fooBar : foo[0]) {
        std::cout << "x=" << fooBar.x << " - y=" << fooBar.y << "\n";
    }
}

Output:

x=1 - y=a
x=2 - y=b
x=3 - y=c

Live demo

Notes:

  1. As you can see above, there's no need for a using statement (in C++, struct bar {...} is already a type).
  2. I used the recommended C++ I/O instead of C's printf (from C++23, there is even a better alternative - std::print).
Sign up to request clarification or add additional context in comments.

5 Comments

I had my reasons but now I will adapt it. Thx
@using. The code is 18 years old. I am adapting it always to the latest C++ standard but I kept the using ... = struct ..... It didn't really bother me but now I removed all of the using ....= parts and all works fine. I upvoted you BTW.
"The code is 18 years old." That's impossible. It contains C++11 features. It can't be older than 14 years.
Just guessing, but maybe the posted code already contains some adaptations to modern C++ (which the OP is gradually doing).
The 1st version was in pure C. Then I upgraded it step by step to C++ and the current standard. Some code just kept "hanging old" and most of the code has been upgraded. So @wohlstad was totally right with his "guess". The code compiles with c++23 and the highest warning level.
0

You can’t directly assign one C-style array to another in C++, that's why foo[0] = myBar; fails. Arrays don’t support the = operator. The reason memcpy() works is because it just does a raw memory copy, but that's not type-safe. A more C++-friendly fix is to use std::array for the inner array (so both the outer and inner parts are assignable), or use std::copy_n / std::to_array to copy the contents.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.