Как Arduino справляется с передачей этого объединения?

Я не уверен, как это будет обрабатываться компилятором Arduino. Если кто объяснит что и почему, буду признателен. Это, очевидно, очень упрощено, но в нем действительно содержится реальная проблема.

На уровне модуля у меня есть этот union. Я понимаю, что это, строго говоря, неправильный C++, но у меня он работает, по крайней мере, когда используется напрямую, а не передается в качестве аргумента функции.

  union _TAT {          // доступ как байты или uint32
    uint32_t wide = 0;
    uint8_t bytes[4];
  };

  _TAT oneTAT;        // переменная _TAT

Предположим, у меня также есть функция, которая работает с ними:

  void fix_Term(_TAT atat) {
    atat.wide = 0;
    atat.bytes[3] = 17;
  }

... и я вызываю его с помощью:

  fix_Term(oneTAT);

Насколько я понимаю, передача AnArray[] эквивалентна передаче *AnArray, поэтому функция может/должна видеть atat.bytes[3] как указатель на этот байт переменной. А как насчет atat.wide? Я не передал явно oneTAT по ссылке, так что...?

Что здесь может произойти на самом деле? Он компилируется без нареканий, но я не могу его протестировать, потому что аппаратное обеспечение, от которого оно зависит, еще недоступно. Кроме того, даже если это сработает, я хотел бы знать почему.

И, конечно же, если это просто неправильно, как мне лучше всего выполнить передачу и изменение такой переменной?

, 👍0

Обсуждение

вы можете протестировать свой собственный код в симуляторе Arduino от tinkercad. Arduino обычно примерно такой же, как простой C++, поэтому проводник компилятора — еще один онлайн-вариант., @dandavis


2 ответа


Лучший ответ:

2

В C и C++ сбивает с толку тот факт, что массивы передаются как указатели, но экземпляр класса, структуры или объединения всегда передается по значению (то есть как копия), включая массивы, которые являются частью пространства памяти структуры как в случае вашего союза.

Если вы хотите передать по ссылке, объявите параметр функции как тип ссылки. Например, void fix_Term(_TAT& atat) {.

,

Спасибо, кажется, это недостающая часть для меня. Я хочу пройти по ссылке, но был сбит с толку (как вы заметили) * / [] ., @Jim Mack


2

Да, передача AnArray[] эквивалентна передаче *AnArray. Но объявление uint8_t *anarray1 не эквивалентно объявлению uint8_t anarray2[4] в структуре/классе/объединении определение. Первый включает в себя указатель на байт в структуре, последний фактически включает в себя 4 байта в структуре. Таким образом, в последнем случае anarray2 уже указывает на данные, и использование variable.anarray2[0] правильно дает вам значение в структуре при вызове variable. anarray1[0] приведет к неопределенному поведению, поскольку указатель указывает куда угодно.

Итак, ваш код компилируется и выполняется без ошибок, но поскольку вы передаете объединение по значению, эффект от вашей функции fix_term отбрасывается, как если бы вы передали обычное значение введите вместо этого (например, int).

,

Однако он может передать его по ссылке: void fix_Term(_TAT & atat) + вызов тот же, а затем он изменит исходную переменную объединения., @KIIV

@KIIV Конечно, но я думаю, что вопрос был о существующем коде., @PMF

Да, вопрос был о том, что делает исходный код, но он также требовал совета, как заставить его работать. Я думаю, теперь понял, благодаря вам и Юраю., @Jim Mack