Künstliche Intelligenz
Elektroauto Xpeng G9 im Test: Lädt schneller als erlaubt
Die Antriebswende trägt mitunter eigenwillige Früchte, und der Xpeng G9 ist ein Spiegelbild dessen. Das 4,9 m lange E-SUV wiegt leer rund 2,3 Tonnen und kann schon in der mittleren Version in 6,4 Sekunden aus dem Stand auf 100 km/h beschleunigen. Das Topmodell lässt gar die meisten der jemals gebauten Porsche 911 hinter sich. Wer es nicht so eilig hat, bewegt diesen Brocken im Schnitt mit dem Heizwert von weniger als zwei Litern Diesel 100 km weit. Bei entsprechender Vorkonditionierung kann die Batterie schneller geladen werden, als es die CCS-Vorgaben derzeit eigentlich erlauben. Finanziell unterbietet der G9 zahlreiche Konkurrenten mit Verbrenner. Sollen diese dann auch nur ansatzweise bei den subjektiven Fahrleistungen mithalten können, ist das Rennen gelaufen, bevor es angefangen hat. Hat die Konkurrenz nun gar keine Chance mehr? Doch, doch, durchaus, denn der Xpeng G9 zeigte im Test einige markante Schwächen.
- Seit Ende 2024 auf dem Markt
- Abmessungen: 4,89 m lang, 1,94 m breit, 1,68 m hoch, Radstand: 3 m
- Leistung: 258 bis 423 kW
- Preis: ab 59.600 Euro
- Größtes Plus: Sehr hohe Ladeleistung
- Größte Schwäche: Sehr umständliche Bedienung
In einem für europäische Verhältnisse riesigen Auto sollte ein ebensolches Platzangebot selbstverständlich sein. Der G9 liefert: Raum gibt es vorn wie hinten mehr als genug, und auch der Kofferraum bietet mit 660 Litern eine angenehme Weitläufigkeit. Etwas getrübt wird das allerdings durch den Umstand, dass Fahrer mit sehr langen Beinen sich einen großzügigeren Verstellbereich nach hinten wünschen. Dem durchschnittlich großen Steuermann wird das freilich kaum auffallen. Ausgesprochen kräftig ist die Massage, die allerdings nicht darüber hinwegtäuschen kann, dass die Sitze an sich trotz zahlreicher Einstellmöglichkeiten und üppiger Abmessungen nicht zu den bequemsten gehören. Irgendwas drückt in der Lehne immer, hielten einige Fahrer in der Redaktion fest. Ungewöhnlich ist die Entscheidung, auch in der zweiten Reihe kaum Abstriche zu machen: Heizung, Lüftung, Massage und eine verstellbare Beinauflage gibt es im G9 auch für die Hinterbänkler.

Ziemlich leise
In einem solch teuren Auto darf der Kunde eine exzellente Geräuschdämmung erwarten, und auch hier sticht der G9 positiv hervor. Selbst bei gehobenem Tempo auf der Autobahn bleibt das E-SUV ziemlich leise, und auf guten Sommerreifen dürften die Abrollgeräusche noch weiter in den Hintergrund rücken. Zusammen mit den im von uns gefahrenen Modell mit Heckantrieb ausgezeichneten Fahrleistungen ergibt sich potenziell ein hervorragend geeignetes Reiseauto für sehr lange Strecken.
Das war die Leseprobe unseres heise-Plus-Artikels „Elektroauto Xpeng G9 im Test: Lädt schneller als erlaubt“.
Mit einem heise-Plus-Abo können Sie den ganzen Artikel lesen.
Künstliche Intelligenz
C++ für eingebettete Systeme: constexpr und consteval
Im heutigen Beitrag zeige ich, wie modernes C++ den Code für eingebettete Systeme beeinflussen kann. Der Code nutzt Features bis zu C++23.
Weiterlesen nach der Anzeige

Andreas Fertig ist erfahrener C++-Trainer und Berater, der weltweit Präsenz- sowie Remote-Kurse anbietet. Er engagiert sich im C++-Standardisierungskomitee und spricht regelmäßig auf internationalen Konferenzen. Mit C++ Insights ( hat er ein international anerkanntes Tool entwickelt, das C++-Programmierenden hilft, C++ noch besser zu verstehen.
Das Beispiel, das ich unten zeige, dreht sich um mindestens zwei Fragen, die mir Kunden schon oft gestellt haben:
- Wozu ist
constevalgut? - Was ist dieser benutzerdefinierte Literal-Operator und warum sollte mich das interessieren?
Ich werde diese beiden Fragen beantworten, aber es nicht dabei belassen. Das unten stehende Beispiel aus der Praxis zeigt auch die neuesten Ergänzungen zu C++, die dazu beitragen, Code robuster und sicherer zu machen.
Was ist eine MAC-Adresse?
Ich gebe viele Kurse für Kunden, die eingebettete Systeme entwickeln. Ich habe lange in diesem Bereich gearbeitet und es hat mir sehr viel Spaß gemacht.
Ein immer wiederkehrendes Thema ist die Vernetzung. Obwohl es heutzutage verschiedene Netzwerktypen und -technologien gibt, wollen wir uns in diesem Beitrag mit dem Internetprotokoll (IP) beschäftigen. Die Basis der Netzwerkkommunikation ist die Netzwerkkarte (NIC). Jede NIC hat eine eindeutige Medium Control Address (MAC) zugewiesen bekommen. Die MAC-Adresse ist die Basis für alles, was darauf aufbaut, wie TCP/IP.
Weiterlesen nach der Anzeige
Eine MAC-Adresse besteht aus genau sechs Bytes. Eine Möglichkeit, eine MAC-Adresse in Code darzustellen, ist folgende:
struct MACAddr {
std::array data;
};
Die für Menschen lesbare Form der MAC-Adresse stellt diese sechs Bytes als Hexadezimalziffern dar, die zu zweit gruppiert und durch einen Doppelpunkt oder einen Bindestrich getrennt sind, wie hier:
12:34:56:78:90:AB
Einige dieser MAC-Adressen sind schon beim Kompilieren bekannt, andere können Nutzer während der Laufzeit eingeben.
Parsen einer MAC-Adresszeichenfolge.
Als ersten Schritt schauen wir uns an, wie eine Funktion, die eine MAC-Adresse in Zeichenfolgenform konvertiert, in eine 6-Byte-Version umgewandelt werden kann. Oben ist MACAddr als Basis. Aus Gründen der Speichersicherheit habe ich mit std::array angefangen. Ich ersetze alle C-Arrays durch die stärkere C++-Version, wo es geht. Der große Vorteil ist, dass ich jederzeit die Größe abfragen kann.
Für die Parsing-Funktion ist eine Zeichenfolge nur dann gültig, wenn sie mindestens 17 Zeichen enthält (6 Bytes mal 2 aufgrund des Hexadezimal-Formats plus 5 Trennzeichen). Das Auffinden der Trennzeichen ist ein weiterer Punkt.
In macFromString ist eine mögliche Implementierung:
constexpr std::expected // #A
macFromString(std::span addr) // #B
{
// #C
if(addr.size() < 17) { return std::unexpected(std::errc::message_size); }
MACAddr res{};
// #D
for(int i = 0; auto& val : res.data) {
// #E
// C++26 will have .at!
if((i < 5) and (addr[2] != ':')) {
return std::unexpected(std::errc::message_size);
}
auto isAllowedHexChar = [](char c) {
return ((('a' <= c) and ('f' >= c)) or // isalpha reduced
(('A' <= c) and ('F' >= c)) or // isalpha reduced
(('0' <= c) and ('9' >= c)) // is digit
);
};
// #F
if(not(isAllowedHexChar(addr[0]) and isAllowedHexChar(addr[1]))) {
return std::unexpected(std::errc::invalid_argument);
}
// #G
if(std::from_chars(addr.data(), addr.data() + 2, val, 16).ec !=
std::errc()) {
return std::unexpected(std::errc::message_size);
}
// #H
addr = addr.subspan((addr.size() >= 3) ? 3 : addr.size());
++i;
}
return res;
}
Ich fange mit dem Rückgabedatentyp std::expected (#A) an. Dieser Typ ist seit C++23 verfügbar. Wie du siehst, ist der erste Template-Parameter der Datentyp, den du im besten Fall erwarten darfst (daher der Name expected), und der zweite Parameter ist der Datentyp für die Fehlerbedingung. Einfachheitshalber habe ich hier std:errc verwendet. Du solltest immer einen Datentypen wählen, der auf die Anforderungen in deiner Codebasis zugeschnitten ist.
Die Stärke von std::expected liegt darin, dass es entweder einen Wert oder einen Fehlercode enthält. Es gibt zwar ungültige MAC-Adressen, aber nehmen wir mal den einfachen Weg und betrachten die Adresse als ungültig, wenn die Zeichenfolge zu kurz ist, die erforderlichen Trennzeichen nicht enthält oder ungültige Zeichen enthält (wie T, das keine Hexadezimalzahl ist). Der Einsatz von std::expected hilft dabei, das Out-Parameter-Muster zu entfernen, das ich ungern mag.
Als Nächstes siehst du, dass macFromString in #B einen std::span als Parameter verwendet. Das Schöne an std::span, der in C++20 hinzugefügt wurde, ist, dass es eine sehr kostengünstige Ansicht der Originaldaten ist, während std::span die Datengröße beibehält. All diese Punkte machen std::span zum perfekten Datentyp, um Array-ähnliche Daten zu übergeben und dabei trotzdem die Grenzen sicher einzuhalten.
Als Erstes prüfe ich in macFromString, ob die Zeichenfolge lang genug ist (#C). Dank std::span ist das nicht nur einfach, sondern auch sicher.
Was passiert, wenn die Zeichenfolge zu kurz ist? Das wäre unerwartet. Deshalb gebe ich in diesem Fall ein std::unexpected mit einem std:errc-Code zurück. Hier zeigt sich die Schönheit von std::expected: Der Fehlerfall wird absolut klar gekennzeichnet.
Schauen wir uns jetzt die Konvertierung an, für die eine Schleife nötig ist. Ich setze eine bereichsbasierte For-Schleife (#D) ein und verwende dafür C++20 mit einem Initialisierer meiner Zählvariablen i.
Ich überprüfe innerhalb der Schleife auf das Trennzeichen, das sich an Position zwei in std::span befindet, wenn wir den letzten Teil nicht betrachten. Das ist dasselbe Verfahren wie oben in #C: Wenn kein Trennzeichen vorhanden ist (oder ein anderes), gebe ich in #D std::unexpected zurück.
In #F wird überprüft, ob die beiden aktuell betrachteten Zeichen im Bereich eines gültigen Hexadezimal-Zeichens liegen. Leider ist std::isdigit nicht constexpr. Das Gleiche gilt für std::isalpha, aber das fehlende constexpr bei dieser Funktion ist nicht so wichtig, da hier ein reduzierter Bereich erforderlich ist.
Als Nächstes kommt in #G die eigentliche Konvertierung. Ich benutze std::from_chars aus C++17. Das Schöne daran ist, dass ich die Werte aus std::span direkt übergeben kann, obwohl sie nicht mit dem üblichen Hexadezimalzahl-Indikator 0x beginnen. Ich kann std::from_chars mitteilen, welche Basis die Zahl hat.
Sollte die Konvertierung fehlschlagen, überprüfe ich den Fehlercode ec[/code und gebe erneut ein [code]std::unexpected zurück. Für deinen Code ist es nützlich, verschiedene Fehlerwerte zu verwenden, um anzuzeigen, an welcher Stelle die Konvertierung fehlgeschlagen ist.
Der letzte Schritt in #H besteht dann darin, das std::span mithilfe seiner subspan-Funktionalität weiterzuschieben. Hier musst du vorsichtig sein: Wenn du den Bereich verlässt, ist das Verhalten undefiniert. Deshalb überprüfe ich, wie viele Elemente noch übrig sind, und gehe entweder um diese Anzahl weiter oder um die Anzahl, die noch übrig ist. Der letzte Teil gilt immer für das letzte Ziffernpaar, das ohne nachfolgendes Trennzeichen kommt.
Es ist wichtig, nicht zu vergessen, i als letzten Schritt zu erhöhen. Dann haben wir einen robusten und sicheren MAC-Adressen-Parser, der die neuesten C++-Funktionen nutzt.
Warum constexpr?
Ein kleines Detail, das ich bei der Erläuterung der Implementierung von macFromString noch nicht angesprochen habe, ist die erste Zeichenfolge in der Funktionsdeklaration, die das Schlüsselwort constexpr bildet.
Die Antwort ist einfach: Wir wollen macFromString zur Kompilierungszeit aufrufen können. Hier kommt der anfangs erwähnte Literal-Operator (UDL) zum Tragen.
Eine interessante Eigenschaft des UDL-Operators ist, dass er nur mit Konstanten zur Kompilierungszeit aufgerufen werden kann. Du kannst den UDL-Operator manuell und damit mit Laufzeitwerten aufrufen, aber das widerspricht völlig dem Zweck eines Operators.
Wir benötigen einen UDL _macaddr, der ein MACAddr-Objekt zurückgibt, damit der folgende Code gültig ist:
// #A
auto data{std::to_array("12:34:56:78:90:AB")};
auto m = macFromString(data);
auto compileTimeMAC = "12:34:56:78:90:AB"_macaddr;
Die Implementierung des UDL-Operators ist recht einfach:
consteval MACAddr operator""_macaddr(const char* str, size_t length)
{
return macFromString({str, length}).value();
}
Ich benutze die UDL-Operatorform, die ein const char* und ein std::size_t nimmt. Der Compiler erkennt freundlicherweise die Größe der Konstantenzeichenfolge zur Kompilierungszeit und teilt sie dem Operator mit. Damit sind alle Informationen zum Aufruf von macFromString vorhanden. Das Beste daran ist, dass die Zeichenfolge und die Länge immer zu 100 % übereinstimmen, da wir absolut nichts damit zu tun haben. Gib einfach die Daten weiter und bilde beim Aufruf von macFromString ein std::span.
Aber macFromString gibt ein std::expected zurück, mehr als nur ein MACAddr. Was tun? Ich rufe einfach .value für das Ergebnis von macFromString auf. Falls std::expected keinen Wert enthält, löst der Datentyp eine Exception aus. Aber ist das nicht schlecht? In anderen Fällen vielleicht schon, aber hier finde ich es mehr als okay, ich finde es großartig!
Hast du das erste Schlüsselwort bemerkt, das ich für den UDL-Operator verwendet habe? Es ist consteval! Ich erzwinge, dass diese Funktion nur zur Kompilierungszeit ausgewertet wird. Bei einer ungültigen MAC-Adresszeichenfolge führt die Ausnahme zum Abbruch des Kompilierungsvorgangs. So kannst du solche Fehler effektiv während der Entwicklung abfangen. Keine fest codierte MAC-Adresse sollte ungültig sein, oder?
consteval hat hier noch einen weiteren Vorteil: Wenn die Implementierung von macFromString nicht constexpr wäre, beispielsweise wegen eines Throw oder anderen undefinierten Verhaltens, würde die Auswertung des UDL zu einem Laufzeitaufruf werden. Das ist sicher nicht das, was du willst.
Robuster, sicherer und besser lesbar
Die gezeigten Elemente helfen dir, deinen Code robuster zu machen und die Sicherheit sowie die Lesbarkeit zu verbessern.
Die Anwendung der neuesten Funktionen von C++ ist in vielerlei Hinsicht vorteilhaft. Eine weitere Erkenntnis: Als Faustregel gilt, dass du jeden UDL-Operator in C++20 und höher als consteval definieren solltest.
(rme)
Künstliche Intelligenz
TDWI Hot Topics: Agentic AI im Unternehmen wirksam machen
Agentic AI geht über klassische GenAI-Anwendungen hinaus, indem sie autonome, zielgerichtete Agenten einsetzt, die Tools verwenden, Entscheidungen unterstützen und Aufgaben über mehrere Schritte hinweg eigenständig ausführen können. Dadurch rückt neben der reinen Modellleistung vor allem die Fähigkeit in den Mittelpunkt, zuverlässige End-to-End-Workflows aufzubauen – inklusive der passenden Balance beim Autonomiegrad, eines pragmatischen Risikomanagements und klar messbarer Ergebnisse.
Weiterlesen nach der Anzeige
Über sieben Stunden ausgewähltes Fachprogramm
Am 22. April widmet sich die Hot Topics einen ganzen Tag lang um die Chancen und Herausforderungen von Agentic AI. Expert:innen aus Beratung, Technologie und Praxis zeigen, wie man geeignete Use Cases identifiziert, Agenten schrittweise in Prozesse integriert und was in der Umsetzung wirklich funktioniert (und was nicht).
Breites Themenspektrum auf der Agenda
Die Veranstaltung richtet sich an IT-Verantwortliche, Digitalisierungs- und Innovationsverantwortliche sowie alle, die sich mit dem produktiven Einsatz von KI-Agenten beschäftigen. Ein zusätzlicher Anreiz für Schnellentschlossene: Noch bis zum 27. März ist das Ticket zum vergünstigten Preis von 249 Euro erhältlich.
Das Online-Event findet am 22. April 2026 statt. Alle Informationen zur Veranstaltung und Anmeldung finden Sie auf der Webseite.
()
Künstliche Intelligenz
Energiemonitor für Balkonkraftwerk bauen und auswerten
Ich habe mir ein Balkonkraftwerk zugelegt und endlich fließt nun auch Sonnenenergie in mein Haus. Leider wusste ich nichts über die Stromflüsse dort, kannte weder Grund- noch Spitzenlasten. Auch wusste ich nicht, wie viele von mir nicht verbrauchte Kilowattstunden ohne Entgelt an den Stromlieferanten abgegeben wurden. Zur Erfassung der Verbrauchsdaten als Basis für die Optimierung des Kraftwerks habe ich nach Maker-Art den in diesem Artikel dokumentierten Energiemonitor realisiert.
- Optischer Lesekopf und flexibles ESP32-basiertes System
- Stromverbrauch und -produktion erfassen
- Dokumentieren und Solarertrag optimieren
Zeitaufwand: 8 Stunden
Kosten: ca. 70 Euro
Material
Werkzeug
- Makerwerkzeug Zangen, Bohrer, Schraubendreher etc.
- Lötutensilien
Anforderungen
Primäres Ziel dieses Projekts war die Messung der aktuell verbrauchten Leistung in kW (umgangssprachlich auch Stromverbrauch genannt) sowie der geleisteten Arbeit in kWh. Der letztgenannte Wert ist einfach durch die Differenz von zwei Zählerständen ermittelbar. Allein die Kenntnis dieser Daten kann Stromfresser wie unnütze Stand-by-Verbraucher aufspüren und damit bereits Energiekosten senken.
In einem nachfolgenden Projekt möchte ich die Werte auch für eine Nulleinspeisung nutzen, das heißt, das Balkonkraftwerk soll nur die im Haus aktuell verbrauchte Leistung liefern, sodass zukünftig die Abgabe an den Netzbetreiber entfällt. Die überschüssige Energie fließt dann in einen Speicher und wird während der Dunkelstunden genutzt. Um dieses Ziel zu erreichen, habe ich mir folgende Anforderungen an mein Projekt gestellt:
Das war die Leseprobe unseres heise-Plus-Artikels „Energiemonitor für Balkonkraftwerk bauen und auswerten“.
Mit einem heise-Plus-Abo können Sie den ganzen Artikel lesen.
-
Künstliche Intelligenzvor 2 MonatenSchnelles Boot statt Bus und Bahn: Was sich von London und New York lernen lässt
-
Social Mediavor 3 WochenCommunity Management zwischen Reichweite und Verantwortung
-
Künstliche Intelligenzvor 2 Wochen
Top 10: Die beste kabellose Überwachungskamera im Test – Akku, WLAN, LTE & Solar
-
Social Mediavor 24 StundenCommunity Management und Zielgruppen-Analyse: Die besten Insights aus Blog und Podcast
-
Datenschutz & Sicherheitvor 3 MonatenSyncthing‑Fork unter fremder Kontrolle? Community schluckt das nicht
-
Entwicklung & Codevor 3 MonatenKommentar: Anthropic verschenkt MCP – mit fragwürdigen Hintertüren
-
Künstliche Intelligenzvor 3 MonatenGame Over: JetBrains beendet Fleet und startet mit KI‑Plattform neu
-
Social Mediavor 3 MonatenDie meistgehörten Gastfolgen 2025 im Feed & Fudder Podcast – Social Media, Recruiting und Karriere-Insights
