Leeres Array: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]

Wenn ich ein Array leer lasse, meldet mir der Compiler bei einer For Schleife ein

warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]

Der Grund wäre mir klar, Anzahl der Elemente ist halt 0, wird fix eingesetzt und dann das < ...

Warum lässt man ein Array leer - weil ich unterschiedliche Boards habe und diese Variablen unterschiedliche Inhalte haben werden.

const byte foo[] {3, 5};
const size_t noOfFoo = sizeof(foo) / sizeof(foo[0]);

const byte bar[] {};          // leer gelassen, weil 
const size_t noOfBar = sizeof(bar) / sizeof(bar[0]);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  for (size_t i = 0; i < noOfFoo; i++)   // OK (wie erwartet)
  {
    Serial.print(F("pin"));
    Serial.print(i);
    Serial.print(" ");
    Serial.println(foo[i]);
  }

  // V1 mein Problem:
  for (size_t i = 0; i < noOfBar; i++)    // warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
  {
    Serial.print(F("pin"));
    Serial.print(i);
    Serial.print(" ");
    Serial.println(bar[i]);
  }
  
  // V2
  if (noOfBar)
  {
    for (size_t i = 0; i < noOfBar; i++)    // keine Warnung, vermutlich weils der Compiler wegoptimiert hat
    {
      Serial.print(F("pin"));
      Serial.print(i);
      Serial.print(" ");
      Serial.println(bar[i]);
    }
  }

  // V3
  int i = 0;
  for (auto &obj : bar)              // kein Vergleich also keine Warnung
  {
    Serial.print(F("pin"));
    Serial.print(i);
    Serial.print(" ");
    Serial.println(obj);
    i++;
  }
}

void loop() {}

V2:
ich könnte das mit einem if umgehen. Dann gibts kein Warning. Ich will aber nicht im Source bei all den For Schleifen ein If drüberhängen . Finde ich "nicht schön"

V3:
Dem range based for ist das leere Array egal, aber da ich einen Zähler in der Schleife brauche, müsste ich vorher einen Zähler definieren und auch manuell erhöhen. Gefällt mir auch nicht.

Hab ich was übersehen, könnte man den Compiler sonst irgendwie beruhigen?

Mir scheint, du suchst den falschen Häck.

Mein Kompiler(avr-gcc-11.1.0 C++17) meldet:

sketch_aug29a:4:12: error: zero-size array 'bar'
    4 | const byte bar[] {};          // leer gelassen, weil
      |            ^~~
exit status 1
zero-size array 'bar'

Beispiel ist enstanden für ESP8266 und beim ESP32 (für die ich das auch brauche)

Am Uno bekomm ich das zweimal,

C:\Daten\myrepository\Arduino\Forum no SVN\20210829_sizeof_0\20210829_sizeof_0.ino: In function 'void setup()':
C:\Daten\myrepository\Arduino\Forum no SVN\20210829_sizeof_0\20210829_sizeof_0.ino:21:24: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
   for (size_t i = 0; i < noOfBar; i++)    // warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
                      ~~^~~~~~~~~
C:\Daten\myrepository\Arduino\Forum no SVN\20210829_sizeof_0\20210829_sizeof_0.ino:32:26: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
     for (size_t i = 0; i < noOfBar; i++)    // keine Warnung, vermutlich weils der Compiler wegoptimiert hat
                        ~~^~~~~~~~~

aber keinen Fehler.

Erfahrungsgemäß, sind solche Häcks nur nötig, wenn ein Fehler im Konzept vorliegt.

Leider sehe ich den Kontext nicht, kann also keinen Rat geben.

ich habe einen Sketch der auf mehrere Boards drauf soll.
Die Boards unterscheiden sich durch die verwendeten Pins.
Also definiere ich mir

#define USE_BOARD 1

#if USE_BOARD == 1
const byte bar[] {3, 5};
#endif
#if USE_BOARD == 2
const byte bar[] {3, 5, 6, 7};
#endif
#if USE_BOARD == 3
const byte bar[] {};
#endif

beim Upload ändere ich das eine USE_BOARD und alles andere soll flutschen.

Tut es eigentlich auch (ESP32 und ESP8266).

Ich wüde da ungern noch ein extra define rund um die "bar" Abschnitte machen ob diese bar überhaupt verwendet werden.

na gut, dann bau ich das um

#ifndef NO_PWMPIN

grml...

Board abfragen und elseif geht nicht?

xy, ... die Unterscheidugn habe ich eh schon drinnen für die Webserver.
es geht aber darum dass es auf der gleichen Plattform unterschiedliche Boards gibt mit unterschiedlichen Pins ...

Wenn Du Pins definierst, sollen die ja irgendwas (geheimes) machen.
In meinen Augen ist damit die Variante mit leerem Array völliger Unsinn.

Gruß Tommy

#include <array>

std::array<byte,0> bar {};         
//std::array<byte,4> bar{3,4,5,6};      

void setup() 
{
  Serial.begin(9600);


  int i = 0;
  for (auto &obj : bar)              // kein Vergleich also keine Warnung
  {
    Serial.print(F("pin"));
    Serial.print(i);
    Serial.print(" ");
    Serial.println(obj);
    i++;
  }
}

void loop() {}

Mit C++20 geht auch
for (int i = 0; auto &obj : bar) // kein Vergleich also keine Warnung

EDIT:
Array Definition schöner gemacht

1 Like

Die pragmatische Anregung von klein Fritzchen:

const byte bar[] {99};

Keine Warnung für ESP32.

1 Like

danke combie für den Vorschlag. Herzchen.

danke agmue, aber dann ist das Array eben nicht leer. und auf "ungültige" pins möchte zur Laufzeit nicht abfrgen.

@all: Da ich aber für C++11 arbeite bleibts vorerst bei einem #define.

Für den Anwender bleibt halt das define in der Konfiguration.
Kryptischer als das leere Array ist das auch eigentlich eh nicht.

Gerne doch!

Das stimmt doch gar nicht.
Die ESP8266 Boarddefinition verwendet per default C++17
Zudem tuts std::array auch mit C++11

Auch ich verstehe diese Notwendigkeit nicht.
Ok, verschiedenen Boards, verschiedenen Pins aber wieso verschiedenen Anzahl von Pins?

Wenns wirklich verschiedene Anzahl von Pins verwendet wird dann soll auch die Verwendung der Pins bei verschiedenen Boards durch bedingte Aufruf von Funktionen bzw bedingtes Kompilieren von Funktionen im Sketch.

Grüße Uwe

Die Boards unterscheiden sich in Anzahl der verwendeten
input pin
digitale output pin
pwm output pin

Und es könnten abhängig vom Board auch eine dieser 3 Arten eben gar nicht vorhanden sein.

Und diese Boards (und andere) bekommen jetzt alle "den gleichen" Sketch. Aber eben mit unterschiedlichen Pindefinitionen.

Ich aktualsiere mal auf die schnelle den Download, falls es jemanden interessiert am ENDE
auf meiner Seite.

getestet mit
1 a generic demo / base configuration for your boards
70 H801 PWM Dimmer
71 the ESP8266 8 channel Relay Board
65 is a one channel Relay board
76 D1 R32 Board from AZ Delivery --> ein ESP32
99 is an example with a NodeMCU V2

es reicht wenn man das #define USE_BOARD umstellt (und eben das Upload Board richtig einstellt).

Da Frage ich mich wieso bei so verschiedener Hardware immer der gleiche Sketch verwendet werden soll.
Du kannst ja auch mit verschiedenen Sketchen aber immer mit der gleichen selbstgeschriebenen Bibliothek benutzen. In der Bibliothek sind alle Funktionen die für alle Hardware gleich bleiben.
Da die Arduini IDE immer alle Dateien im Sketch-Direktory vor dem Kompilieren zusammenfügt kann das auch als Teilsketche realisiert werden. Achtung das zusammenfügen erfolgt alfabetisch.

Grüße Uwe