Pin-Deklaration byte vs int

Holla zusammen, mal wieder möchte ich etwas hinterfragen:

In vielen Sketches werden die Pin-Zuweisungen (LEDs, Taster, Sensoren,...)
mit dem Typen "int" vorgenommen.

Warum wird da nicht "byte" genommen (bis 255, was ja auch reichen sollte) ?

Hat int da einen Vorteil, welchen ich noch nicht sehe?

Ich danke euch :slight_smile:

progger:
Hat int da einen Vorteil, welchen ich noch nicht sehe?

Ja, man muss nicht nachdenken :wink:

Gruß Tommy

Hat int da einen Vorteil, welchen ich noch nicht sehe?

Ja, int hat Vorteile.
Nur nicht hier!

  1. es wird niemals negative Pins geben können
  2. digitalWrite() und seine Brüder erwarten uint8_t, was (quasi) das gleiche wie Byte ist.

Warum wird da nicht "byte" genommen (bis 255, was ja auch reichen sollte) ?

Das weiß ich auch nicht.

Besser wäre:

constexpr byte irgendeinPin {13};

Denn ändern wird sich ein Pin zur Laufzeit nicht.

(deleted)

Damit verbaust Du dem Compiler jegliche Möglichkeit zur Prüfung.

Gruß Tommy

Peter-CAD-HST:
die Präprozessor-Direktive #define

Einige der C++ Spracheigenschaften zielen darauf ab, eben solche Defines vermeiden zu können.

Meine Meinung:
Dann doch lieber int.

progger:
In vielen Sketches werden die Pin-Zuweisungen (LEDs, Taster, Sensoren,...)
mit dem Typen "int" vorgenommen.

Das zeigt, was viele machen, muß noch lange nicht richtig sein!

Wenn ein Pin als Konstante festgelegt wird, wird kein wertvoller Variablenspeicher verschwendet, was auch wichtig sein kann. Beispiel:

const byte pinName = 5;

Ich glaube so

const byte pinName {5};

wäre es "perfekt" ?

Die speicherfreundliche Art des Typs "const" habe ich hier auch schon gelernt 8)

Dann bin ich zumindest bei dem Thema auf dem für mich noch sehr, sehr langen, richtigen Weg :slight_smile:

Danke für eure Unterstützung!

(deleted)

progger:
wäre es "perfekt" ?

... wegen der Typprüfung, die sonst nicht stattfindet, wenn ich mich recht erinnere.

Auch schreibe ich

enum  {WARTEN, MINZEIT, LEDZEIT};

besser wäre:

enum class Schritt:byte {WARTEN, MINZEIT, LEDZEIT};

Hallo,

@ agmue: richtig erinnert

@ Peter: Sagen wir mal so. C++ beschreitet den unaufhaltsamen Weg die Präprozessor-Direktive zu ersetzen. Eben weil man damit meistens unbewusst Unsinn machen kann. Genauso wie mit dem einfachen enum ohne class. Man freut sich vielleicht das es endlich fehlerfrei kompiliert und wundert sich später warum es doch nicht so sauber funktioniert wie erdacht. Weil man vielleicht beim enum die falsche Variable überschrieben hat o.ä. Bei define Makro Orgien gibts meistens Klammerfehler, womit das Ergebnis anders ist wie es sollte usw.

Eines ist auch klar. Die Tipparbeit mit C++ nimmt zu. Dafür gibts mehr "Sicherheit" zurück. Der Compiler kann und wird mehr meckern bei gefühlten Kleinigkeiten. Inwieweit das mit Arduino Sinn macht weiß ich nicht. Manches schreibe ich Testweise mit aktuellen avr-gcc 10.2. Ohne fremde Libs gibts Warnungen etc. die man selbst beheben kann. Nutzt man "fremde" Libs gibts gefühlt Millionen von Warnungen, die kann man kaum selbst beheben. Man sitzt in einem Zwiespalt. Bleibt man noch beim avr-gcc 9.3 oder quält man sich auf Grund der Warnungen mit 10.x rum. Die Arduino IDE bringt den avr-gcc 7.3 mit. Wobei man mit avr-gcc 9.3 sprich C++17 schon wirklich sehr viel machen. C++20 kam ja erst frisch raus und wird auch erst in der nächsten Zeit einen so großen Umbruch einläuten wie damals C++11. Das brauch alles seine Zeit. Das Neue im Standard muss erstmal verstanden, in Bücher gegossen, best practice Erfahrung gesammelt werden, Bücher überarbeitet usw..

avr-gcc 10.2 möchte ich erstmal nur dazu nutzen um den Syntax mit dem ich so rumdokter auf dem aktuellen Stand zu halten. Sonst gehts mir so wie die fremden Libs die dann später Tausende Warnungen generieren. Das spätere qualvolle überarbeiten möchte ich mir ersparen.

grad in der wiring_digital.c nachgesehen:

void pinMode(uint8_t pin, uint8_t mode)
void digitalWrite(uint8_t pin, uint8_t val)
int digitalRead(uint8_t pin)

dann schwenk ich ab jetzt in meinen neuen Sketches auch von const byte auf const uint8_t um...

(deleted)

Peter-CAD-HST:
och, dann müssen die Präprozessor-Direktiven sofort verboten werden, oder ?

Natürlich!
Da wo es "unvernünftig" ist, diese einzusetzen.
Das ist keine vernünftige Sprache!

Und das definieren von konstanten Dingen, ist sowas....

#define pin 13
Ist eine doofe Textersetzung, ohne jede Plausibilitätsprüfung

int pin = 13;
Tuts, ist aber nicht schön
braucht 2 Byte Ram
Und negative Pins gibts eh nicht.

byte pin = 13;
erledigt das Problem.
Alternativ, uint8_t statt byte, macht keinen echten Unterschied.

byte pin {13};
ist die moderne Variante
Warum?
Weil dir der Kompiler ein
byte pin {13.47};
schnurstracks um die Ohren haut.

Dann gibts ja noch das const, oder readonly

const byte pin {13};
So weiß der Kompiler dass sich der Wert während des Programmablauf niemals ändern darf.
Versuchst du das, hagelt es Meldungen.

Aber kann er das wegoptimieren?
So einbauen wie ein Define?
Jain!
Du könntest ja einen Zeiger darauf richten.
Oder die Konstante in 2 Übersetzungseinheiten verwenden.
Nicht alles kann er erahnen.

Jetzt kann man dem Kompiler etwas unter die Arme greifen und ihm sagen, was man will:

static inline const byte pin {13};
Das hilft dem Optimierer ordentlich aufs Pferd.
Haben aber alle noch den Charakter einer Empfehlung.
Bis auf static und inline, sie sorgen dafür , dass gleichlautende in allen Übersetzungseinheiten vorliegen dürfen

Um ihn zu zwingen

constexpr byte pin {13};
Das ist die wahre und endgültig beste Form!

Leute, super Austausch :slight_smile:

Teils schwere Kost, aber sehr interessant und informativ!