Pufferüberlauf trotz Verwenden von snprintf() - wie finde ich den Fehler?

Hallo liebe Programmiergemeinde,

ich habe vermutlich einen Pufferüberlauf in meiner Ventilatorsteuerung mit meinem Arduino Mega und ich weiß nicht, wie ich das Problem eingrenzen soll.

Ich schreibe in eine Variable einen Text. Dieser erscheint dann nach einer Weile in einer anderen, eigentlich konstanten Variable. Sieht für mich nach Pufferüberlauf aus. Da ich den Inhalt der Variable mit snprintf() schreibe, dürfte das doch eigentlich nicht passieren?

Was meint ihr, was sonst als Ursache in Frage kommt und habt ihr eine Idee, wie ich den Fehler eingrenzen kann?

Hier im Detail:

Ich habe eine Klasse ‚cStatus‘ definiert. Diese hat als Eigenschaft u. a. einen String ‚char statusString[145]‘, der nur in der Funktion ‚switchVent()‘ der Klasse beschrieben wird:

class cStatus {
  public:
    ...
    char statusString[145] = "";
    bool switchVent();
    void getLCDstrA(char*LCDstr,byte len=0);
    bool isVentOn();
}
bool cStatus::switchVent() { 
  ...
  snprintf(this->statusString, 145, " ... [diverse Formatangaben] ...",
           [diverse Byte-, Integer- und Stringvariablen]
		);
}

In der Funktion ‚getLCDstrA‘ dieser Klasse habe ich zwei lokale, konstante Strings definiert, die nicht verändert werden. Das Funktionsergebnis wird im Hauptprogramm loop() für eine Displayausgabe verwendet:

void cStatus::getLCDstrA(char*LCDstrA, byte len) {
  const char txtOn[4] =" An";
  const char txtOff[4]="Aus";
  ...
  snprintf(LCDstrA, len, "%02d:%02d:%02d -- --  %s   ", 
           hour(), minute(), second(),   
           this->isVentOn() ? txtOn : txtOff
           );    
  ...
}

Nachdem das Programm eine Weile korrekt läuft ändert sich der Inhalt des konstanten Strings ‚txtOn‘ und ‚txtOff‘ und somit der Display-Ausgabe. Dort finden sich dann plötzlich Inhalte aus dem ‚statusString‘. Irgendwann schmiert das gesamte Programm ab.

Für mich war das eindeutig ein Pufferüberlauf beim Beschreiben ‚statusString‘, d.h. es wird mehr in den String geschrieben als die zuvor definierten 145 Zeichen und damit in den Speicherbereich von ‚txtOn‘ und ‚txtOff‘ hinen. Aber ich dachte die Funktion snprintf() sollte sowas abfangen. Somit bin ich mit meine Ideen der Ursachensuche am Ende.

Ich könnte mir vorstellen, dass irgendwo im Programmspeicher die Adresse der beiden lokalen Variablen ‚txtOn[4]‘ und ‚txtOff[4]‘ manipuliert wird, und daher fälschlicherweise Werte aus dem Speicherbereich des Status ausgegeben werden. Aber wie kann sowas passieren und wie grenze ich den Fehler ein?

Danke schonmal für eure Unterstützung!

Bitte den vollständigen Sketch mit Links zu den verwendeten Bibliotheken.
Du verwendest entweder zuviel Strings, Schreibst über den Index eines Arrays hinaus oder macht falsche Sachen mit Pointern.
Grüße Uwe

und wie grenze ich den Fehler ein?

Erstmal ausgrenzen!
Dann diagnostizieren und eingrenzen.

Denn bisher zeigst du nur fehlerfreien Code.(wie mir scheint)
Vielleicht nicht schön, aber der Fehler steckt woanders.

Tipp:

  1. Der Fehler steckt immer da, wo man zuletzt sucht.
  2. Der Weg in die Debugginghölle ist mit falschen Annahmen gepflastert.

Danke schonmal,

combie:
Erstmal ausgrenzen!
Dann diagnostizieren und eingrenzen.

Wenn ich die Zeile auskommentiere, in dem der 'statusString' mit snprintf() beschrieben wird, tritt der Fehler schonmal nicht mehr auf. Allerdings ist dieser ja scheinbar nicht das eigentliche Problem.

uwefed:
Bitte den vollständigen Sketch mit Links zu den verwendeten Bibliotheken.

OK, dann werde ich schauen, wie das Projekt maximal reduzieren kann und der Fehler trotzdem noch auftritt. Es ist etwas größer mit 4 Klassen zur Programmsteuerung, für die Sensoren, fürs Protokollieren an Thingspeak und für die Anzeige.

Ich habe nun einen Monat lang Testreihen gefahren, um den Fehler einzugrenzen. Das hat ewig gedauert, weil es teilweise mehrere Tage dauerte, bis das System abstürzte und ich auch nicht jeden Tag Zeit dafür habe.

Wirklich schlauer geworden bin ich nicht. Ich habe eine Klasse “cNetLog”, die einen String über das Ethernet-Modul an thingsspeak.com sendet. Wenn ich diese rausprogrammiere, dann braucht es bis zu einer Woche bis zum Absturz, mit ihr ca. einen Tag.

Ich wäre wirklich dankbar, wenn einer von Euch (@uwefed?) mal drüberschauen könntet, ob es einen offensichtlichen Fehler gibt. Es sind allerdings schon 4 Klassen mit einigen Funktionen. Ich habe sie sehr intensiv kommentiert und versucht, übersichtlich zu programmieren.

Wenn ich mich irgendwie erkenntlich zeigen kann, so schreibt mir eine PM.

Der Code überschreitet die Maximallänge eines Posts, deswegen anbei als Zip-Datei das ganze Projekt.

Zu euren Hinweisen

"Zu viel Strings"

Ich habe drei längere Strings (1x 194 und 2x 296 Zeichen), die konstant im Speicher sind, alles andere ist kürzer und nur während der Funktionsaufrufe im Speicher. Ist das zu viel für einen Arduino Mega?:

  • eine 194 Zeichen lange String-Variable in der Klasse “cStatus” ( char statusString[194] = “”, in ‘Status.h’ Zeile 48 ). Die Variable wird in der Funktion cStatus::SwitchVent() per snprintf() gefüllt ( ‘Status.cpp’ Zeile 62ff). Sie wird zum Protokollieren der Systemvariablen bei thinkspeak.com genutzt. Von der Klasse “cStatus” gibt es nur eine Instanz im Speicher.
  • eine 296 Zeichen lange String-Variable in der Klasse “cNetlog” ( char PrioLogString[296] = “”, in ‘Netlog.h’ Zeile 23 ). Sie wird in der Funktion cNetlog::PrioUpdateWebService() per strcpy() gefüllt ('Netlog.cpp, Zeile 47). Hier wird ein Protgokoll des Systemzustands zum Zeitpunkt des Schaltens zwischengespeichert, da thinkspeak.com nur aller 15 Sekunden Werte annimmt. Von der Klasse “cNetlog” gibt es ebenfalls nur eine Instanz im Speicher.
  • jeweils ein 296 Zeichen langer String in “setup()” und in “loop()” ( char netLogString[296] in den Zeilen 55 und 80 ). Eine der beiden Variablen liegt damit quasi ständig im Speicher. Sie enthält das in der Klasse “cStatus” erzeugte Protokoll und gibt sie an die Klasse “cNetlog”.
  • ein 21 Zeichen langer String lokal in der Funktion “displayLCD()” im Hauptscript Zeile 134. Damit wird das LCD-Displays gefüllt.

Zudem gibt es noch 8 konstante Strings, die über das F-Makro in den Programmspeicher verlegt wurden ( Klasse “cNetLog”, Zeile 6ff in ‘Netlog.cpp’ ).

Was die eingebundenen Bibliotheken blocken, weiß ich nicht, hier die Scriptgrößenangaben beim Kompilieren:
31152 Bytes (12%) des Programmspeicherplatzes
2062 Bytes (25%) des dynamischen Speichers
+ lokale Variablen.
"Schreibst über den Index eines Arrays hinaus"

Ich hab abgesehen von den Strings nur bei “cStatus::SwitchVent()” einen lokalen Array (byte switchResult[6] = {1,1,1,1,1,1} ‘Status.cpp’ Zeile 63).

"falsche Sachen mit Pointern"

  • Die String-Funktionen von “cStatus” und “cSensor” funktionieren mit Zeigern, z. B. :
    void cStatus::getLCDstrA(char*LCDstr, byte len)
  • Zudem wird im die MAC-Adresse des Ethernet-Shields per Zeiger an den Konstruktor der Klasse “cNetlog” übergeben:
    cNetlog::cNetlog(uint8_t*mac)

Erläuterung der Scripte:

Anbei im Dateianhang nun die Skripte der Lüftungssteuerung, die sich festfährt.

Die Steuerung schaltet einen Lüfter in Abhängigkeit von Feuchtigkeit und Temperatur von zwei Sensoren, gibt Ergebnisse auf einem 4-Zeilen LCD aus und loggt sie bei thingspeak.com.

Zur Info: Die Makros mit “D_” und “DV_” beginnen, sind nur zum Debuggen und aktuell ausgeschaltet.

Hauptsscript (nutzt <Arduino.h>)

  • “kellerlueftung”
    In der Funktion "loop()" wird der Überlauf von millis() abgefangen, werden Tastendrücke erkannt und diverse Klassenfunktionen aufgerufen.
    In der Funktion “displayLCD()” wird das LCD gefüllt.

Klasse cNetLog - sendet einen String an thingspeak.com über das Ethernet-Shield (nutzt <Ethernet.h>):

  • “Netlog.h”
  • “Netlog.cpp”

Klasse cSensor - liefert die Werte eines Feuchte&Temperatursensors und berechnet den Taupunkt (basierend auf <DHT.h>, nutzt <math.h>):

  • “Sensor.h”
  • “Sensor.cpp”

Klasse cStatus - schaltet den Ventilator und gibt Statuswerte und Texte zurück (nutzt <Wire.h> und <TimeLib.h>):

  • “Status.h”
  • “Status.cpp”

Klasse cLCD - zum Anzeigen auf LCD und Steuern der LCD-Hintergrundbeleuchtung (basiert auf <LiquidCrystal_I2C.h> und nutzt <Wire.h>):

  • “LcdJo.h”
  • “LcdJo.cpp”

Makros, um aus den gespeicherten Zentel Werten (z. B. -123 Zentel) Dezimalzahlen zu machen (-12,3) und Konstanten zur Vorgabe der Länge der langens Strings:

  • “Helpers.h”

Die ausgeschalteten Debugging-Makros:

  • “Debug.h”

Von der Klasse "cStatus" gibt es nur eine Instanz im Speicher.

Dann mach doch (testweise) daraus was Globales/Statisches.

weil das ist imho nix

Doch,schon.

char text[21] = "";  // reserviert 21 Byte und schreibt in das erste eine 0

text[1] bis text[20] sind natürlich undefiniert

Nachdem das Programm eine Weile korrekt läuft ändert sich der Inhalt des konstanten Strings ‚txtOn' und ‚txtOff'

Das kann alles mögliche sein, leider.
Deine Vermutung würde bei

const char* txtOn = " An";

evtl. zutreffen. (Passiert da dasselbe?) Aber das wäre eigentlich egal.

joboe:
Ich wäre wirklich dankbar, wenn einer von Euch (@uwefed?) mal drüberschauen könntet,

Wenn ich mich irgendwie erkenntlich zeigen kann, so schreibt mir eine PM.

Ja.
NEIN!
und nu Thema.
Und ich sehe Kommentare, die mir zu Denken geben...
// MAC-Adresse (muss im lokalem Netzwerk einmalig sein!)
Ich schliesse mich noiasca an, das ggfls an irgendeiner Stelle eine feste Verdrahtung eines Arrays dazu führt, das sich Speicherbereiche überschneiden.
Für mich ist das derzeit zu umfangreich, um da "hinterzusteigen", da ich die ausgelagerten Funktionen jeweils in einem neuen Fenster einsehen muss und damit das aktuelle nicht mehr verfügbar ist - geschuldet der Displaygröße ;(
Vielleicht hat ja combie als cpp-Spezi oder Renter als Klassen-Fuchs ne Idee...

Hallo,

vielleicht sollte der TO erstmal seine Libs aufräumen. Es hilft nicht wenn man Arduino.h mehrfach einbindet und mehrfach im gleichen Headerfile. Netlog.h Zeile 18 fehlt ein Anführungszeichen. Sonst schlägt die Auskommentierung fehl.
Alle Fehlermeldungen rauskopiert sieht so aus.
Du musst die Libs an den richtigen Stellen einbinden und eine Mehrfacheinbindung deiner Libs verhindern. Am einfachsten mit
#pragma once im Headerfile. Schau dir dazu die Libs an die in der Arduino Installation stecken.

Error while detecting libraries included by C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\kellerlueftung.ino.cpp
Error while detecting libraries included by C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\Netlog.cpp
In file included from C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\Netlog.h:49,
                 from C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\Netlog.h:49,
                 from C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\Netlog.h:49,
                 ...
                 from C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\Netlog.h:49,
                 from C:\Users\Doc\AppData\Local\Temp\arduino_build_611844\sketch\Netlog.h:49,
                 from C:\Users\Doc\AppData\Local\Temp\arduino_modified_sketch_696481\kellerlueftung.ino:32:
Netlog.h:6:77: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
    6 | #include <Arduino.h>                          // Arduino-Standard-Bibliothek
      |                                                                             ^
Netlog.h:7:78: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
    7 | #include <Ethernet.h>                         // Steuerung des Netzwerkmoduls
      |                                                                              ^
Netlog.h:8:92: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
    8 | #include "Sensor.h"                           // für Klasse cSensor (aktuelle Sensordaten)
      |                                                                                           ^
Netlog.h:9:102: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
    9 | #include "Status.h"                           // für Klasse cStatus (Einstellungen und Prozessdaten)
      |                                                                                                     ^
Netlog.h:44:62: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   44 | #include <Arduino.h>           // Arduino-Standard-Bibliothek
      |                                                              ^
Netlog.h:45:92: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   45 | #include "Debug.h"             // Makros v.a. zum Ausgeben Debuggen über Seriellen Monitor
      |                                                                                           ^
Netlog.h:46:61: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   46 | #include "LcdJo.h"             // für Klasse cLCD (Display)
      |                                                            ^
Netlog.h:47:77: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   47 | #include "Sensor.h"            // für Klasse cSensor (aktuelle Sensordaten)
      |                                                                            ^
Netlog.h:48:93: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   48 | #include "Status.h"            // für Klasse cStatus (Ventilatorsteuerung und Prozessdaten)
      |                                                                                            ^
Netlog.h:49:78: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   49 | #include "Netlog.h"            // für Klasse cNetlog (Netzwerkkommunikation)
      |                                                                             ^
Netlog.h:50:53: error: #include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)
   50 | #include "Helpers.h"           // eigene Helferlein
      |                                                     ^
exit status 1
#include nested depth 200 exceeds maximum of 200 (use -fmax-include-depth=DEPTH to increase the maximum)

Hallo,

habe begonnen das inkludieren aufzuräumen, dann erhalte ich jedoch Haufenweise
error: ... was not declared in this scope
error: expected identifier before numeric constant
Ne das wird so leider nichts.

Vielen Dank, dass ihr euch das Skript angeschaut habt und Bitte um Entschuldigung, dass es Fehler hat, die es bei euch nichtmal zum Compilieren bringt. Beim Zippen hat es mehrere Klassen durcheinandergehauen. Wie das passieren konnte ist mir ein Rätsel. Vorm Zippen hatte ich es compiliert, ohne dass eine Fehlermeldung kam. Im Anschluss habe ich nur noch den API-Key anonymisiert, wobei ein Anführungszeichen verloren gegangen ist. Womöglich ist es dort passier. Oh, Mann, so schade um eure Zeit, tut mir leid!

Anbei nochmal das Script, diesmal habe ich es vor dem Hochladen nochmal entpackt und danach wieder compiliert - ohne Fehler (Arduino-Programmierumgebung 1.8.13).

Im Script habe ich alle #include gelöscht, die nicht mehr gebraucht werden.

Den Hinweis von michael_x mit const char * txtOff =“AUS” statt const char txtOff[4]=“AUS” habe ich eingebaut, der Test läuft.

Doc_Arduino:
habe begonnen das inkludieren aufzuräumen, dann erhalte ich jedoch Haufenweise …
Ne das wird so leider nichts.

Das liegt vermutlich an dem oben beschriebenen Missgeschick.

Ich dachte das doppelte #include wäre nicht tragisch, da in den entsprchenden Dateien ein #pragma once steht. Aber vielleicht verstehe ich es falsch. Sind meine Annahmen richtig:

  • Wenn ich in einem Datei eine Funktion aus z. B. der arduino.h-Bibliothek verwende und keines der bereits verlinkten Bibliotheken dies auch tut, so muss ich in jeder Datei wo ich das mache #include <arduino.h> voranstellen.
  • Wenn ich Makros, Funktionen oder Konstanten in eine eigene Datei ‘Helpers.h’ auslagere, müssen in allen Dateien wo sie verwendet werden ein #include “Helpers.h” stehen. Bei ‘Helpers.h’ oben ein #pragma once
  • Wenn ich im Hauptsscript Objektvariablen global definiere, z. B. für die Klassen A und B, muss ich dort die Headerdateien der entsprechenden Klassen A und B verlinken (# inklude “KlasseA.h” und “KlasseB.h”)
  • In den .cpp Dateien ‘KlasseA.cpp’ und ‘KlasseB.cpp’ muss ich ebenso die Headerdateien verlinken (#include “KlasseA.h” und “KlasseB.h”)
  • Wenn eine Klassenvariable der Klasse A auf eine die Klasse B referenziert und in A Funktionen der Klasse B benutzt werden, dann muss auch das bei ‘KlasseA.h’ ein #include “KlasseB.h” stehen
  • Weil dadurch die ‘KlasseB.h’ von mehreren Stellen aus verlinkt wird, muss dort ein #pragma once stehen

Auf die anderen Posts antworte ich auch noch.

Vielen Dank schon vorab,
Jochen!

kellerlueftung2.zip (18.3 KB)

Hallo Noiasca,

noiasca:
…ansonsten würde ich mal grundsätzlich alle hardcoded Array Größen prüfen (und ändern!) besonders dann wenn später mit hardcocded for i = … gearbeitet wird.

solche Konstrukte finde ich Brand gefährlich:

    for (i=1; i<6; i++) {

if (switchResult[i] == 0) switchVentOn = false;
   }




da vertut man sich schnell mal - ändert die Array Größe vergisst aber dann auf die Funktionsblöcke.

Ist daran gefählich, dass ich mit “6” die Größe hart vorgebe und oben beim Deklarieren ggf. versehendlich einen kleineren Wert verwende?

Meinst du es besser so?:

    const int MAX=5;
    int feld[MAX];    
    for (i=0; i<MAX; i++)
    { 
         ...
    }

Worauf muss ich auchten außer darauf, dass ich in Schleifen nicht über die Grenze hinauslaufe?

Hab neben dem zitierten Array nur das Array mit der fest gecodete MAC-Adresse. Das übergebe ich aber nur an die entsprechende Klasse aus ‘Ethernet.h’ und mache sonst nichsts damit. Das ist einem Beispiel entnommen.

Zudem habe ich nur einige String-Arrays.

Grüße,
Jochen

Noch eine Option ist es die Größe durch den Compiler über den sizeof() Operator ausrechnen lassen. Nur aufpassen dass sizeof() eines Zeigers die Größe eines Zeigers ist. Wenn man also Arrays an Funktionen übergibt muss man i.d.R. die Größe extra übergeben

Gegen die sizeof() Fehlbedienung kann man sich wehren, in dem man auf sizeof() verzichtet.

Vorschlag:
Einmal um die Zellen eines realen Arrays zu zählen und einmal die eines Datentypes.
Wenn man versucht NichtArrays zu zählen, hauts einem der Kompiler um die Ohren.
Die Auswertung erfolgt zur Kompilezeit, kein Laufzeitcode.

template<typename ArrayType, size_t count> 
constexpr size_t arrayCount(const ArrayType (&)[count])
{
  return count;
}

template<typename ArrayType> 
constexpr size_t arrayCount()
{
  constexpr ArrayType temp {0};
  return arrayCount(temp);
}


using MeinArrayType = int[24];

MeinArrayType testArray;


void setup() 
{
  Serial.begin(9600);
  Serial.println(arrayCount(testArray));
  Serial.println(arrayCount<MeinArrayType>());
}

void loop() 
{

}

body of constexpr function ‘constexpr size_t arrayCount() [with ArrayType = int [24]; size_t = unsigned int]’ not a return-statement

Mit “const” funktioniert es auch bei mir.

template<typename ArrayType, size_t count>
constexpr size_t arrayCount(const ArrayType (&)[count]) {
  return count;
}

template<typename ArrayType>
const size_t arrayCount() {
  constexpr ArrayType temp {0};
  return arrayCount(temp);
}

using MeinArrayType = int[24];

MeinArrayType testArray;

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println(arrayCount(testArray));
  Serial.println(arrayCount<MeinArrayType>());
}

void loop() {}

Getestet mit dem ESP8266 Core 2.7.4.

Gruß Fips

Oha

Da hast du wahr!
Das tuts erst mit C++14
(ist mir leider bisher noch nicht aufgefallen)

combie:
C++14

Schade, EspCore also auch noch bei 11!

Gruß Fips

Danke für die Tipps, allerdings übersteigt das meine Kenntnisse. Ich nehme mir erstmal den esten zum Herzen, der ist leichtverständlich. Allerdings scheint das eine Array im Code nicht das Problem zu sein, warum sich der Script festfährt, das ist ja scheinbar i. O. Mehr Arrayverarbeitung ahbe ich nicht, abgesehen von Strings, di ich an Funktionen übergebe und dort meist mit snprintf() gefüllt werden. An 7 Stellen kopiere ich Strings mit strcpy(), ist ja mitunter auch eine Quelle von Fehlern. Davon allerdings 4 mal nur strcpy(mystring,"");

Ich habe schlichtweg keine Idee mehr und befürchte, das Projekt aufgeben zu müssen. Ich versuche es mal mit einem Watchdog. Das ist aber eine echt schlechte Lösung, denn bis der Watchdog den arduino neu startet, kann das Programm durch undefinierte Zustäne Mist verzapfen.

Vielleicht liegt das Problem ja auch in einer der genutzten Bibliotheken, z. B. der <LiquidCrystal_I2C.h>? Ist sowas wahrscheinlich?

Betrieb ohne Display habe ich noch nicht versucht, dass mach ich jetz mal.

Oder kann am Arduino etwas kaputt sein (ist ein Nachbau von “SunFounder”)?

Es wäre echt schön, wenn einer von euch den Code wenigstens überfliegt, vielleicht mache ich ja grundsätzlich etwas falsch.

Vielleicht liegt der Grund wirklich in includierten Bibliotheken. Eben kam beim Compilieren untenstehende Warnungen. Beim nächsten Compilieren kamen die aber nicht mehr, obwohl ich nichts verändert habe.

In file included from D:\Jochen\Arduino\libraries\NewLiquidCrystal_lib\LiquidCrystal_SR1W.cpp:48:0:
D:\Jochen\Arduino\libraries\NewLiquidCrystal_lib\LiquidCrystal_SR1W.h:168:1: warning: multi-line comment [-Wcomment]
 //             |    |      0.1uF            |     \
 ^
In file included from C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\Ethernet\src\Dns.cpp:8:0:
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\Ethernet\src\Dns.cpp: In member function 'uint16_t DNSClient::BuildRequest(const char*)':
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\Ethernet\src\utility/w5100.h:457:25: warning: result of '(256 << 8)' requires 18 bits to represent, but 'int' only has 16 bits [-Wshift-overflow=]
 #define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )
                      ~~~^~~
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\Ethernet\src\Dns.cpp:164:18: note: in expansion of macro 'htons'
  twoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG);
                  ^~~~~