Revision f23f1330-ec07-4015-868f-db748ef9d071 - Arduino Stack Exchange

Try replacing

```c++
taskDefinition _tasks [ ] [4] = {
```

by

```c++
taskDefinition _tasks [ ] = {
```

In short, you have defined `_tasks` as a 2D array of objects (an array
of arrays of objects) while you intend to use it as a 1D array.

------------------------------------------------------------------------

Note that the error message is quite explicit if you take the time to
parse it:

> request for member 'task' in '\_tasks[((int)i)]',

You are requesting `_tasks[i].task`,

> which is of non-class type

but `_tasks[i]` is not an object.

> type 'taskDefinition [4]'

It is instead an array of four `taskDefinition` objects.

------------------------------------------------------------------------

**Edit**: Fixing the answer to match the latest version of the question.

Your code works, but not quite as you expect it to work. You wrote:

```c++
complexTaskDefinition tasks [ ] [4] = ...;
```

Here you are defining a 2D array of objects, while your intention was to
define a one-dimensional array (why do I feel like I am repeating
myself?).

```c++
complexTaskDefinition tasks [ ] [4] = {
 {taskC1, true, -1, 1000 },
 {taskC2, true, 10, 2000 },
 {taskC3, false, 3, 3000 },
};
```

This definition, although syntactically correct, is awfully wacky. You
are defining `tasks` as an array of 3 items. Each item is itself an
array of 4 objects, where the first object of the array is explicitly
initialized, and the three others are implicitly initialized to
all-bits-zero. So basically your definition is equivalent to this
explicit version:

```c++
complexTaskDefinition tasks [3] [4] = {
 {{taskC1, true, -1, 1000 }, {nullptr, false, 0, 0},
 {nullptr, false, 0, 0}, {nullptr, false, 0, 0}},
 {{taskC2, true, 10, 2000 }, {nullptr, false, 0, 0},
 {nullptr, false, 0, 0}, {nullptr, false, 0, 0}},
 {{taskC3, false, 3, 3000 }, {nullptr, false, 0, 0},
 {nullptr, false, 0, 0}, {nullptr, false, 0, 0}}
};
```

Then you wrote:

```c++
task = tasks [ i ];
```

Here, `tasks[i]` is a row of the 2D array, i.e. a 1D array of 4 objects,
whereas `task` is a pointer to object. The assignment is legit because
here, like in most contexts, the array “decays” to a pointer to its
first element. The above line is equivalent to the explicit version:

```c++
task = &tasks[i][0];
```

Quite fortunately, this happens to point to one of the elements of the
array that has been explicitly initialized!

As an illustration of the above, here is a modified version of
`showComplexTaskList()` that loops over _all_ the tasks in the array:

```c++
void showComplexTaskList () {
 Serial.println ( F ( "\nComplex Task List:" ) );
 Serial.print(F("number of tasks: "));
 Serial.println(sizeof tasks / sizeof(complexTaskDefinition));
 for (uint8_t i = 0; i < TASK_COUNT; i++) {
 for (uint8_t j = 0; j < 4; j++) {
 task = &tasks[i][j];
 Serial.print ( '[' );
 Serial.print ( i );
 Serial.print ( F ("]["));
 Serial.print ( j );
 Serial.print ( F ( "] REPEAT:" ));
 Serial.print ( ( task->repeat ) ? "YES" : "NO" );
 Serial.print ( F ( ", DELAY:" ) );
 Serial.print ( task->delay );
 Serial.print ( F ( ", ITERATIONS:" ) );
 Serial.print ( task->iterations );
 Serial.println ();
 }
 }
}
```

Its output is:

```text
Complex Task List:
number of tasks: 12
[0][0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
[0][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][0] REPEAT:YES, DELAY:2000, ITERATIONS:10
[1][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][0] REPEAT:NO, DELAY:3000, ITERATIONS:3
[2][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][3] REPEAT:NO, DELAY:0, ITERATIONS:0
```

So your program works almost by chance: an error in the way you define
the array cancels an error in the way you use it. This kind of cancelled
error method is very bad programming practice. You are wasting memory in
unused `complexTaskDefinition` objects. More importantly, your code
doesn't express your intent, which makes the program way harder to
understand and to debug.

The fix is to declare a 1D array, as this has always been the intention:

```c++
complexTaskDefinition tasks [ ] = {
 {taskC1, true, -1, 1000 },
 {taskC2, true, 10, 2000 },
 {taskC3, false, 3, 3000 },
};
```

Now, you can check that this array does only have three tasks, as
reported by `sizeof tasks / sizeof(complexTaskDefinition)`. To use the
array, you can use a pointer if you want:

```c++
task = &tasks[i];
// ...
Serial.print ( ( task->repeat ) ? "YES" : "NO" );
```

Or you can directly request a member of `tasks[i]`, as in

```c++
void showComplexVersion () {
 Serial.println ( F ( "\nComplex Version:" ) );
 for (uint8_t i = 0; i < TASK_COUNT; i++) {
 tasks[i].task();
 }
}
```

Now I have a question for you. Since I already explained your 1D vs. 2D
array mistake in the first iteration of my answer, why did you persist
with this in your edited question? If you are going to blatantly ignore
the answers you get, at least say so in the question. This could save
time to those who might consider helping you.

AltStyle によって変換されたページ (->オリジナル) /