ESP8266 Stürzt ab

Gast #6170427
Lesenswert?

Hallo,

ich habe einen ESP8266 und folgendes Problem:

Wenn ich eine Exception schmeiße stürzt der ESP ab.

Exception:
1
struct NtpError_EXCEPTION : public std::exception
2
{
3
    const char* what() const throw ()
4
    {
5
        return "NTP failed";
6
    };
7

8
    const uint16_t code() const throw ()
9
    {
10
        return 10;
11
    };
12
};

Schmeißen der Exception:
1
throw NtpError_EXCEPTION();

Exceptions sind aktiviert und ich lade diese Library:
1
#include <exception>

Kennt jemand eine Lösung für das Problem?
Danke im Vorraus.

TR.OLL
Gast #6170571
Lesenswert?

Platformio.ini
1
[env:d1_mini]
2
platform = espressif8266@2.0.4
3
board = d1_mini
4
framework = arduino
5
monitor_speed = 115200
6
build_flags = -fexceptions
7
build_unflags = -fno-exceptions
8

9

10
lib_deps = 
11
  git+https://github.com/xreef/PCF8591_library.git#master
12
  git+https://github.com/ich423/LCDMenuLib2.git
13
  ;git+https://github.com/Jomelo/LCDMenuLib2.git
14
  git+https://github.com/adafruit/RTClib.git#master
Beitrag #6170579 wurde von einem Moderator gelöscht.
Beitrag #6170628 wurde von einem Moderator gelöscht.
Gast #6170676
Lesenswert?

Unabhängig vom Quelltext würde ich gerne auch mal sehen, wie du die 
Stromversorgung gelöst hast. Schaltplan und Foto. Weil: Mangelhafte 
Stromversorgung ist nach meiner Erfahrung die häufigste Ursache von 
Ausfällen dieser Art.
Gast #6170707
Lesenswert?

Wenn man unbehandelte Exceptions sehen möchte, sollte man die Baudrate 
des Seriellen Monitors (oder eines beliebigen Terminals) auf 74880 Baud 
stellen.


Ansonsten, fix mal eben getestet unter Arduino, Exceptions 
funktionieren, kein "Absturtz".
Und das mit einer Stromversorgung, von der Stefanus unbeirrbar 
behauptet, dass sie nicht funktioniert.


Testcode:
1
#include <Streaming.h>
2
#include <exception>
3

4
struct NtpError_EXCEPTION : public std::exception
5
{
6
  const char* what() const throw ()
7
  {
8
    return "NTP failed";
9
  };
10

11
  const uint16_t code() const throw ()
12
  {
13
    return 10;
14
  };
15
};
16

17

18
void setup()
19
{
20
  Serial.begin(74880);
21
 
22
  Serial << "Start: " << __FILE__ << endl;
23
}
24

25
void loop()
26
{
27
  try
28
  {
29
    throw NtpError_EXCEPTION();
30
  }
31
  catch (const NtpError_EXCEPTION& e)
32
  {
33
    Serial << "Exception gefangen" << endl;
34
  }
35

36
  delay(1000);
37
}


Ausgabe:
1
 ets Jan  8 2013,rst cause:2, boot mode:(3,7)
2

3
load 0x4010f000, len 1392, room 16 
4
tail 0
5
chksum 0xd0
6
csum 0xd0
7
v3d128e5c
8
~ld
9
Start: ESP_Exception_001.ino
10
Exception gefangen
11
Exception gefangen
12
Exception gefangen
13
// usw
Gast #6170724
Lesenswert?

Stefan ⛄ F. schrieb:
> nabhängig vom Quelltext würde ich gerne auch mal sehen, wie du die
> Stromversorgung gelöst hast. Schaltplan und Foto. Weil: Mangelhafte
> Stromversorgung ist nach meiner Erfahrung die häufigste Ursache von
> Ausfällen dieser Art.

Über den USB-Anschluss von einem wemos d1 mini.
Gast #6170729
Lesenswert?

TR.OLL schrieb:
> Über den USB-Anschluss von einem wemos d1 mini.

Wenn er bei Exceptions immer abstürzt, wird die Stromversorgung wohl 
nicht die Ursache sein. Passiert es aber nur manchmal, empfehle ich Dir 
ein möglichst dickes USB Kabel und einen 100µF Kondensator direkt am 
ESP-Modul an VCC und GND. Das NodeMCU Board, das offenbar als Vorlage 
für die Wemos D1 Boards verwendet wurde, hat diesen Kondensator mit 
drauf.
Gast #6170748
Lesenswert?

Stefan ⛄ F. schrieb:
> TR.OLL schrieb:
>> Über den USB-Anschluss von einem wemos d1 mini.
>
> Wenn er bei Exceptions immer abstürzt, wird die Stromversorgung wohl
> nicht die Ursache sein. Passiert es aber nur manchmal, empfehle ich Dir
> ein möglichst dickes USB Kabel und einen 100µF Kondensator direkt am
> ESP-Modul an VCC und GND. Das NodeMCU Board, das offenbar als Vorlage
> für die Wemos D1 Boards verwendet wurde, hat diesen Kondensator mit
> drauf

Ohne Exceptions stützt der ESP nich ab, also ist die Stromversorgung 
nicht das Problem.

Arduino Fanboy D. schrieb:
> Es ist dieses Board gemeint: Ebay-Artikel Nr. 233174130261

Ich nutze dieses Board: https://wiki.wemos.cc/products:d1:d1_mini
Gast #6170821
Lesenswert?

Ich habe mich in den letzten Tagen intensiv mit der Stromversorgung der 
ESP8266 beschäftigt, Stefan F. (stefanus) hat recht; oft fehlt ein 
100µF, auf den Wemos und Nachbauten sind meist nur 3x 10µF drauf, die 
zudem noch andere Chips versorgen, auf dem blanken ESP8266 ist gar 
keiner drauf, drinnen vermutlich ein 100nF, auf manchen Lolin Borads 
tatsächlich 100µF. Ausserdem werden oft MCP1700 u.ä. verbaut, die sind 
zu schwach, liefern nur 250mA (und dann mit leichtem Spannungseinbruch), 
der ESP8266 zieht aber bis zu 400mA.
(Firma: @home) #6170828
Lesenswert?

Arduino Fanboy D. schrieb:
> Und das mit einer Stromversorgung, von der Stefanus unbeirrbar
> behauptet, dass sie nicht funktioniert.

es ist ein grosser unterschied, ob einige am küchentisch funktionieren, 
wie bei dir, oder in einer serienproduktion ohne nennenswerte ausfälle!

ich kann jede aussage von stefan zur esp8266 stromversorgung nur 
unterstreichen und bestätigen.

mit weniger verständnis und erfahrung sieht vieles leichter aus.
man könnte auch sagen - doof, aber glücklich und das ja auch nicht so 
schlecht als über-/lebenstrategie.


mt
Gast #6170843
Lesenswert?

TR.OLL schrieb:
> Ist im Anhang.

Also keine Meldung in der Form:
> User exception (panic/abort/assert)
> Unhandled C++ exception: NTP failed

Sondern:
> Abort called

Also kein willkürlicher "Absturz" durch z.B. Stromversorgung, sondern 
ein kontrolliertes Abbrechen in irgendeinem Programmteil.

Der Stackdump zeigt dir wo Abort aufgerufen wird.



> rst cause:2
Ist in dem Fall ok
1
  reset causes:
2
        0:
3
        1: normal boot
4
        2: reset pin
5
        3: software reset
6
        4: watchdog reset
Gast #6170887
Lesenswert?

Arduino Fanboy D. schrieb:

> Sondern:
>> Abort called
>
> Also kein willkürlicher "Absturz" durch z.B. Stromversorgung, sondern
> ein kontrolliertes Abbrechen in irgendeinem Programmteil.
>
> Der Stackdump zeigt dir wo Abort aufgerufen wird.

Und sorgt man darf das der ESP das Programm nicht abricht und neustartet 
sonder weiterläuft.
Gast #6170909
Lesenswert?

Apollo M. schrieb:
> es ist ein grosser unterschied, ob einige am küchentisch funktionieren,
> wie bei dir, oder in einer serienproduktion ohne nennenswerte ausfälle!
Die Adapter werden in Serie produziert!

Auf Nachfrage wo der Stefanus mal irgendwann davon gehört hat, ob ein 
solcher Adapter jemals versagt hat, kamen Plattitüden.

Apollo M. schrieb:
> ich kann jede aussage von stefan zur esp8266 stromversorgung nur
> unterstreichen und bestätigen.
Ich kann bestätigen, dass der ESP bei zu großen Schwankungen versagt.


Wobei "mir" das mit "dem" Adapter noch nicht passiert ist.
Auch nicht mit seinen Brüdern.

Der Adapter ist mit einem 1000µF Stützkondensator auf der 3,3V Seite 
ausgerüstet.
Stefanus fordert irgendwo 100µF

Der darauf befindliche Regler wird bei dieser Exception 
Beispielanwendung mit weniger als 80mA versorgt, im Mittel.
Der Regler zeigt eine Erwärmung von ca 10°C über Umgebung im 
Dauerbetrieb.

Die Spannung am aufgesteckten ESP Board zappelt zwischen 3,33V und 
3,26V.
Das ist voll im Rahmen.

Jetzt kannst du natürlich behaupten, dass meine ganzen diese Adapter 
Ausnahmefälle sind und nur durch Zufall funktionieren.

Apollo M. schrieb:
> mit weniger verständnis und erfahrung sieht vieles leichter aus.
> man könnte auch sagen - doof, aber glücklich und das ja auch nicht so
> schlecht als über-/lebenstrategie.
Und mich auch für blöd erklären, wenn es dir damit besser geht.
#6170927
Lesenswert?

Es ist Fakt daß der ESP recht anspruchsvoll ist, was die Stromversorgung 
betrifft. Insofern hat Stefan Recht.
Er hat hier auch nirgendwo behauptet, daß das in diesem Fall auch so 
ist.
Ob das jetzt für Deinen oder den Aufbau des TO zutrifft, weiß aufgrund 
fehlender Infos niemand.
Und ja, solche Abstürze führen oft zu denn merkwürdigsten Effekten.
Gast #6170935
Lesenswert?

Leute, kommt mal wieder runter. Ich denke, diese Diskussion um die 
Stromversorgung hilft dem TO nicht weiter. Sein Modul stürzt 
reproduzierbar immer an der gleichen Exception ab und nicht bei anderen 
Aktionen. Damit ist die Stromversorgung sicher nicht seine aktuelle 
Problemursache.
Gast #6170944
Lesenswert?

Andreas B. schrieb:
> Und ja, solche Abstürze führen oft zu denn merkwürdigsten Effekten.
Welche dann an unterschiedlichsten Stelle auftauchen können.

Hier haben wir keinen willkürlichen Absturz.
Sondern einen Abort.
Scheinbar reproduzierbar.

Und ja, über den Grund kann man nur spekulieren......
Denn der verursachende Code ist ja geheim, und damit völlig untestbar.
Und der Stackdump unausgewertet.




Dieser Code funktioniert:
(nochmal leicht modifiziert, das (nötige?) virtual hinzugefügt und ein 
überflüssiges const entfernt, usw)
1
#include <Streaming.h>
2
#include <exception>
3

4

5
class NtpError_EXCEPTION : public std::exception
6
{
7
  public:
8
  virtual const char* what() const throw() override
9
  {
10
    return "NTP failed";
11
  };
12

13
  virtual uint16_t code() const throw()
14
  {
15
    return 10;
16
  };
17
};
18

19

20

21
void setup()
22
{
23
  Serial.begin(74880);
24
 
25
  Serial << "Start: " << __FILE__ << endl;
26
}
27

28
void loop()
29
{ 
30
  try
31
  {
32
    throw NtpError_EXCEPTION();
33
  }
34
  catch (const NtpError_EXCEPTION& e)
35
  {
36
    Serial << "Exception gefangen! " 
37
           << " Code: " << e.code()
38
           << " What: " << e.what() 
39
           << endl;
40
  }
41

42
  delay(1000);
43
}
Gast #6171129
Lesenswert?

Arduino Fanboy D. schrieb:
> Andreas B. schrieb:
>> Und ja, solche Abstürze führen oft zu denn merkwürdigsten Effekten.
> Welche dann an unterschiedlichsten Stelle auftauchen können.
>
> Hier haben wir keinen willkürlichen Absturz.
> Sondern einen Abort.
> Scheinbar reproduzierbar.
>
> Und ja, über den Grund kann man nur spekulieren......
> Denn der verursachende Code ist ja geheim, und damit völlig untestbar.
> Und der Stackdump unausgewertet.

Bei mir geht der Code auch.

Codeteil der die Exceptions nutzt:
1
time_t getNtpTime()
2
{
3
    try {
4
        IPAddress ntpServerIP; // NTP server's ip address
5
        while (Udp.parsePacket() > 0); // discard any previously received packets
6
        // get a random server from the pool
7
        WiFi.hostByName(ntpServerName, ntpServerIP);
8
        Serial.print("ntpServerName: ");
9
        Serial.println(ntpServerName);
10
        Serial.print("ntpServerIP: ");
11
        Serial.println(ntpServerIP);
12
        sendNTPpacket(ntpServerIP);
13
        uint32_t beginWait = millis();
14
        while (millis() - beginWait < 5000) {
15
            int size = Udp.parsePacket();
16
            if (size >= NTP_PACKET_SIZE) {
17
                Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
18
                // convert four bytes starting at location 40 to a long integer
19
                secsSince1900 = (unsigned long)packetBuffer[40] << 24;
20
                secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
21
                secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
22
                secsSince1900 |= (unsigned long)packetBuffer[43];
23
                timeSource = true;
24

25
                if (rtcRunning == false && timeSource == true) {
26
                    rtc.adjust(DateTime(year(), month(), day(), hour(), minute(), second()));
27
                    rtcRunning = true;
28
                }
29
                return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
30
            }
31
        }
32
        Serial.println("ERROR NTP");
33
        if (rtcConnected == true && rtcRunning == true) {
34
            throw NtpError_EXCEPTION();
35
        }
36
        else {
37
            return 0;
38
        }
39
    }
40
    catch (NtpError_EXCEPTION& e) {
41
        if (e.code() == 10) {
42
            if (rtcConnected == true && rtcRunning == true) {
43
                DateTime now2 = rtc.now();
44
                timeSource = false;
45
                return (now2.unixtime() - secs_between_1900_and_1970) - 2208988800UL + timeZone * SECS_PER_HOUR;
46
            }
47
            else {
48
                return 0;
49
            }
50
        }
51
    }
52
  return 0;
53
}
Gast #6171156
Lesenswert?

TR.OLL schrieb:
> Wie kann man das kontrollierte abrechen verhindern?


Die Ursache suchen!
z.B. den Stackdump analysieren.
In der Arduino Welt gibt es den "ESP Exception Decoder"
Da könntest du eine Chance mit haben.

Ansonsten gefällt mir diese Zeile nicht wirklich.
> while (millis() - beginWait < 5000)
Ein delay(0) oder yield() in der Schleife ist sicherlich kein Fehler.
Denn der ganze WLAN Kram läuft in einer anderen Task und benötigt Zeit.
Gast #6171162
Lesenswert?

Hier der Teil von dem Programm, wo der Fehler liegt:

Exceptions.h
1
//exceptions.h
2
#ifndef EXCEPTIONS_H
3
#define EXCEPTIONS_H
4

5
#include <exception>
6

7
struct NtpError_EXCEPTION : public std::exception
8
{
9
    const char* what() const throw ()
10
    {
11
        return "NTP failed";
12
    };
13

14
    const uint16_t code() const throw ()
15
    {
16
        return 10;
17
    };
18
};
19

20
#endif

Timecontrol.cpp (der Code mit dem Problem).
1
#include "TimeControl.h"
2
#include <ESP8266WiFi.h>
3
#include <WiFiUdp.h>
4
#include <exception>
5
#include "RTClib.h"
6

7
#include "config.h"
8
#include "exceptions.h"
9

10
#define NTP_PACKET_SIZE 48
11

12
WiFiUDP Udp;
13
RTC_DS1307 rtc;
14

15
static const char ntpServerName[] = "pool.ntp.org";
16
unsigned int localPort = 8888;
17
int timeZone;
18
byte packetBuffer[NTP_PACKET_SIZE];
19
unsigned long secsSince1900;
20
bool rtcConnected = false, rtcRunning = false;
21
bool timeSource = true; // true = NTP, false = rtc
22

23

24
time_t getNtpTime();
25
void sendNTPpacket(IPAddress &address);
26

27
TimeControl& TimeControl::getInstance()
28
{
29
  static TimeControl instance;
30
  return instance;
31
}
32

33
TimeControl::TimeControl()
34
{
35
}
36

37
void TimeControl::start()
38
{
39
  //loadUtcDiff(&timeZone);
40
  //loadSummertimeAuto(&summerTimeAuto);
41
    if (rtc.begin() == true) {
42
        rtcConnected = true;
43

44
        if (rtc.isrunning() == true) {
45
            rtcRunning = true;
46
            Serial.println("RTC is running");
47
        }
48
        else {
49
            Serial.println("Rtc is not running");
50
            rtcRunning = false;
51
        }
52
    }
53
    else {
54
        Serial.println("Rtc disconnected");
55
        rtcConnected = false;
56
    }
57

58
  Udp.begin(localPort);
59
  setSyncProvider(getNtpTime);
60
  setSyncInterval(3600);
61
}
62

63
void TimeControl::getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss)
64
{
65
  *hh = hour();
66
  *mm = minute();
67
  *ss = second();
68
  if (summerTimeAuto && isSummertime())
69
  {
70
    *hh += 1;
71
    if(24 == *hh)
72
    {
73
      *hh = 0;
74
    }
75
  }
76
}
77

78

79
unsigned long TimeControl::secSince1970(){
80
 return now(); 
81
}
82

83
void TimeControl::rtcSync()
84
{
85
    if (timeSource == true) {
86
        rtc.adjust(DateTime(year(), month(), day(), hour(),minute(),second()));
87
    }
88
}
89

90
time_t getNtpTime()
91
{
92
    try {
93
        IPAddress ntpServerIP; // NTP server's ip address
94
        while (Udp.parsePacket() > 0); // discard any previously received packets
95
        // get a random server from the pool
96
        WiFi.hostByName(ntpServerName, ntpServerIP);
97
        Serial.print("ntpServerName: ");
98
        Serial.println(ntpServerName);
99
        Serial.print("ntpServerIP: ");
100
        Serial.println(ntpServerIP);
101
        sendNTPpacket(ntpServerIP);
102
        uint32_t beginWait = millis();
103
        while (millis() - beginWait < 5000) {
104
            int size = Udp.parsePacket();
105
            if (size >= NTP_PACKET_SIZE) {
106
                Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
107
                // convert four bytes starting at location 40 to a long integer
108
                secsSince1900 = (unsigned long)packetBuffer[40] << 24;
109
                secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
110
                secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
111
                secsSince1900 |= (unsigned long)packetBuffer[43];
112
                timeSource = true;
113

114
                if (rtcRunning == false && timeSource == true) {
115
                    rtc.adjust(DateTime(year(), month(), day(), hour(), minute(), second()));
116
                    rtcRunning = true;
117
                }
118
                return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
119
            }
120
        }
121
        Serial.println("ERROR NTP");
122
        if (rtcConnected == true && rtcRunning == true) {
123
            throw NtpError_EXCEPTION();
124
        }
125
        else {
126
            return 0;
127
        }
128
    }
129
    catch (NtpError_EXCEPTION& e) {
130
        if (e.code() == 10) {
131
            if (rtcConnected == true && rtcRunning == true) {
132
                DateTime now2 = rtc.now();
133
                timeSource = false;
134
                return (now2.unixtime() - secs_between_1900_and_1970) - 2208988800UL + timeZone * SECS_PER_HOUR;
135
            }
136
            else {
137
                return 0;
138
            }
139
        }
140
    }
141
  return 0;
142
}
143

144

145
void sendNTPpacket(IPAddress &address)
146
{ // set all bytes in the buffer to 0
147
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
148
  // Initialize values needed to form NTP request
149
  // (see URL above for details on the packets)
150
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
151
  packetBuffer[1] = 0;     // Stratum, or type of clock
152
  packetBuffer[2] = 6;     // Polling Interval
153
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
154
  // 8 bytes of zero for Root Delay & Root Dispersion
155
  packetBuffer[12] = 49;
156
  packetBuffer[13] = 0x4E;
157
  packetBuffer[14] = 49;
158
  packetBuffer[15] = 52;
159
  // all NTP fields have been given values, now
160
  // you can send a packet requesting a timestamp:
161
  Udp.beginPacket(address, 123); //NTP requests are to port 123
162
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
163
  Udp.endPacket();
164
}
165

166

167
bool TimeControl::isSummertime(void)
168
{
169
  if (month() < 3 || month() > 10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
170
  if (month() > 3 && month() < 10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
171
  if ((month() == 3 && (hour() + 24 * day()) >= (1 + timeZone + 24 * (31 - (5 * year() / 4 + 4) % 7))) || (month() == 10 && (hour() + 24 * day()) < (1 + timeZone + 24 * (31 - (5 * year() / 4 + 1) % 7))))
172
    return true;
173
  else
174
    return false;
175
}
176

177

178
void TimeControl::setTimeZone(int newTimezone)
179
{
180
  timeZone = newTimezone;
181
  //saveUtcDiff(timeZone);
182
  //setSyncProvider(getNtpTime);
183
}
184

185
int TimeControl::getTimeZone()
186
{
187
 return timeZone;
188
}
189

190

191
void TimeControl::setSummertimeAuto(bool newState)
192
{
193
 summerTimeAuto = newState;
194
 //saveSummertimeAuto(summerTimeAuto);
195
}
196

197

198
bool TimeControl::getSummertimeAuto()
199
{
200
 return summerTimeAuto;
201
}

Platformio.ini
1
;PlatformIO Project Configuration File
2
;
3
;   Build options: build flags, source filter
4
;   Upload options: custom upload port, speed and extra flags
5
;   Library options: dependencies, extra library storages
6
;   Advanced options: extra scripting
7
;
8
; Please visit documentation for the other options and examples
9
; https://docs.platformio.org/page/projectconf.html
10

11
[env:d1_mini]
12
platform = espressif8266@2.0.4
13
board = d1_mini
14
framework = arduino
15
monitor_speed = 115200
16
build_flags = -fexceptions
17
build_unflags = -fno-exceptions
18

19

20
lib_deps = 
21
  git+https://github.com/xreef/PCF8591_library.git#master
22
  git+https://github.com/ich423/LCDMenuLib2.git
23
  ;git+https://github.com/Jomelo/LCDMenuLib2.git
24
  git+https://github.com/adafruit/RTClib.git#master
Gast #6171974
Lesenswert?

TR.OLL schrieb:
> Hier der Teil von dem Programm, wo der Fehler liegt:
Wo du meinst, dass der Fehler sein müsste.

Leider ist auch dieser Code untestbar, da aus dem Zusammenhang gerissen.
Auch sind meine Vorschläge/Korrekturen dort noch nicht eingearbeitet.
Zusätzlich: Aktiviere doch mal alle Warnungen und beseitige diese.

Was hat der ESP Exception Decoder ergeben?
Bestätigt dieser deine Diagnose?

TR.OLL schrieb:
> Bei mir geht der Code auch.
Immerhin ist damit klar, dass Exceptions grundsätzlich funktionieren, 
oder habe ich dich falsch verstanden?
#6172942
Lesenswert?

TR.OLL schrieb:
> Peter K. schrieb:
>> Allgemein würde ich im Embedded Bereich von Excpetions jeglicher Art
>> abraten.
>
> Warum?

Ist zwar schon ein weilchen her, aber ich Antworte da dennoch drauf.

Excpetions sind in Programmen welche gewisse Echtzeitbedinungen erfüllen 
müssen besonders kritisch, weil Exceptions je nach Implementierung 
extrem lange brauchen. Das fügt einen relativ großen Jitter ein weil 
eine Funktion viel viel länger benötigt wenn eine Exception geworfen 
wird als wenn das nicht der Fall ist.
Bei einem einfachen Returnvalue ist das nicht der Fall.
Das betrifft allerdings nur Codepfade welche eine konstante oder 
möglichst kurze Laufzeit haben sollten, in anderen ist es durchaus 
möglich.

Exceptions verleiten aber auch oft dazu Code zu schreiben welcher den 
Heap verwendet, was bei Embedded Systemen ohne Speicherbereinigung nicht 
passieren sollte.
Jede Speicherallocation auf dem Heap kann zu dessen Fragmentierung 
führen und irgendwann kann es sein, dass der Heap derart fragmentiert 
ist, dass ein call von new malloc oder alle anderen Dinge welche 
implizit den Heap verwenden nicht mehr funktionieren.

Der ISO C++ Standard schreibt dazu:
A throw-expression initializes a temporary object, called the exception 
object. The memory for the exception object is allocated in an 
unspecified way.

Es ist also nicht definiert wo und wie dieser Speicher erzeugt wird und 
es kann daher durchaus sein, dass der Speicher auf dem Heap alloziert 
wird.

Bei uns in der Arbeit haben wir daher in den Codingguidelines Excpetions 
komplett verboten und wir machen alles über Returnvalues. Das ist zwar 
mehr schreibarbeit, führt aber zu einem mehr vorhersehbaren Code.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren