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
E-Auto-Prämie wie angekündigt im Bundestag beschlossen – Kritik an Förderregeln
Das neue Förderprogramm für Elektroautos kann wie angekündigt rückwirkend für Zulassungen seit Jahresanfang in Anspruch genommen werden. Das hat der Bundestag in Berlin beschlossen. Beantragen lässt sich der staatliche Zuschuss aber noch nicht, weil die entsprechende Internet-Plattform erst gestartet werden muss. Dies soll nach früheren Angaben im Mai passieren.
Weiterlesen nach der Anzeige
Den Details der neuen Kaufprämie muss das Parlament nicht zustimmen. Vorgesehen ist, dass die staatliche Förderung von Privatkunden beim Kauf von reinen Elektroautos, Plug-in-Hybriden und Elektroautos mit Range Extender beantragt werden kann. Je nach Fahrzeugart und persönlichen Umständen liegt sie zwischen 1500 und 6000 Euro. Allerdings gibt es Einkommensobergrenzen, bis zu denen sie ausgezahlt wird. Diese liegen bei 80.000 Euro Haushaltseinkommen im Jahr, mit zwei Kindern bei 90.000 Euro.
Förderung nach Einkommen und Kinderzahl
Die Basisförderung beträgt für reine Elektroautos 3000 Euro. Für Haushalte mit einem Einkommen von maximal 60.000 Euro gibt es 4000 Euro, für Haushalte mit einem Maximal-Einkommen von 45.000 Euro 5000 Euro. Pro Kind steigt die Förderung um 500 Euro, insgesamt um höchstens 1000 Euro. Weniger Geld gibt es für sogenannte Plug-in-Hybride, die sowohl mit Strom als auch mit Treibstoff fahren können. Für diese Autos und für Fahrzeuge mit Range Extender liegt die Basisförderung bei 1500 Euro. Range Extender sind kleine Verbrennungsmotoren, die die Reichweite von Elektroautos erhöhen.
Grüne sehen Fehlanreiz
In der Bundestagsdebatte kritisierte Till Steffen von den Grünen, dass mit der Förderung von Plug-in-Hybriden und Range-Extender-Fahrzeugen die „absolut falschen Anreize“ gesetzt würden. Denn diese würden im Prinzip mit Benzin fahren. Von der Kaufprämie profitierten zudem Besserverdienende. „Wir brauchen ein Angebot, wo sich eben auch die Krankenschwester auf dem Land ein günstiges, kleines Elektroauto leisten kann. Die lassen Sie im Regen stehen“, sagte Steffen an die Adresse der Regierungskoalition.
Mehr Informationen zur Elektroauto-Förderung
(fpi)
Künstliche Intelligenz
Apple erhöht Recycling-Anteil in Produkten – aber immer noch nur bei 30 Prozent
Apple will die Quote an recycelten Rohstoffen und Herstellungsmaterialien, die für seine Produkte verwendet werden, weiter erhöhen. Der Konzern teilte im Rahmen seines neuen „Umweltfortschrittsberichts“ mit, den bislang „höchsten Anteil an recycelten Materialien aller Zeiten in seinen Produkten” erreicht zu haben. Das Problem: Über die gesamte Modellpalette sind dies bislang nur 30 Prozent. Allerdings gibt es bei einzelnen Gerätebestandteilen eine deutlich höhere Quote.
Weiterlesen nach der Anzeige
Kobalt, Gold, Papier
In Verpackungen will Apple schon seit längerem keinen Kunststoff mehr verwenden, dies wurde nun auch bei den letzten noch verbliebenen Geräten umgesetzt. Die Verpackungen auf Faserbasis könnten problemlos recycelt werden, zum Anteil an Altpapier machte Apple keine Angaben, Frischpapier werde aber „verantwortungsvoll“ beschafft. In Akkus sollen „ab sofort“ 100 Prozent recyceltes Kobalt stecken. Die seltenen Erden für Magneten sind ebenfalls zu 100 Prozent wiedergewonnen – das ist angesichts weltweiter Verknappungen auch wirtschaftlich sinnvoll.
Bei Leiterplatten verwendet Apple nun zu 100 Prozent recycelte Vergoldungen samt Lötzinn. Apple gab an, durch Verpackungsumstellungen „mehr als 15.000 Tonnen Plastik“ eingespart zu haben. Besonders große Kartons lassen sich für das Recycling zusammenfalten. Displayschutzfolien wurden durch papierbasierte Materialien ersetzt oder ganz weggelassen.
Müll maschinell erfassen
Apple berichtet im Umweltfortschrittsbericht, der hier nachgelesen werden kann, auch über neuartige Recyclinganlagen. Im sogenannten Advanced Recovery Center in Kalifornien steht demnach „Cora“, die dank fortschrittlicher Sensorik eine „Präzisionszerkleinerung” mit höheren Raten der Materialrückgewinnung erlaubt.
„Apple hat zusätzlich A.R.I.S.entwickelt, ein neues, auf maschinellem Lernen basierendes Erkennungssystem, das Recyclingunternehmen dabei unterstützt, Elektronikschrott effizient zu klassifizieren und zu sortieren“, so das Unternehmen. Ein technisches Paper zu dem System wurde frei veröffentlicht. A.R.I.S. läuft auf einem Mac mini, das System wird gerade mit verschiedenen Partnern aus der Müllbranche getestet, um möglichst auch bei anderen Unternehmen zum Einsatz zu kommen. Apple gibt seine Umwelttechnologie traditionell auch an Konkurrenten weiter, falls diese sie wünschen.
Weiterlesen nach der Anzeige
(bsc)
Künstliche Intelligenz
OpenAI kontert Anthropic mit großem Codex-Update
OpenAI hat seine Codex-Anwendung für Desktops mit einem großen Update erweitert. Die wichtigste Neuerung ist die Computernutzung im Hintergrund: Codex soll Anwendungen auf dem eigenen Rechner direkt bedienen können, indem es Bildschirminhalte erkennt, klickt und Texte eingibt. Laut OpenAI können mehrere Agenten parallel im Hintergrund arbeiten, ohne andere Apps zu stören. Die Funktion ist zunächst auf macOS beschränkt und soll bald auch in der EU verfügbar werden.
Weiterlesen nach der Anzeige
Zusätzlich arbeitet die Codex-Anwendung künftig direkt mit dem Web: Eine integrierte Browseransicht erlaubt es, Seiten zu kommentieren und dem Agenten so gezielt Anweisungen zu geben. Die Anwendung kann nun zudem Bilder generieren und direkt im Arbeitsprozess verfeinern, etwa für Entwürfe von Benutzeroberflächen, Mockups oder Spielgrafiken. Ergänzend baut OpenAI die Integration in bestehende Werkzeuge aus: Mehr als 90 neue Plug-ins verbinden Codex mit Diensten wie Jira, GitLab Issues oder der Microsoft Suite. So kann der Assistent mehr Kontext aus verschiedenen Anwendungen einbeziehen und darüber auch Aktionen ausführen.
OpenAI bringt zudem eine Vorschau auf eine Erinnerungsfunktion: Die Anwendung kann sich künftig Vorlieben, Korrekturen und bereits gesammelte Informationen merken. Das soll helfen, künftige Aufgaben schneller und mit weniger zusätzlicher Anleitung zu erledigen. Darauf aufbauend soll die App proaktiv Vorschläge machen, etwa für nächste Arbeitsschritte, und relevante Aufgaben aus verschiedenen Diensten bündeln und priorisieren. Die meisten dieser Funktionen werden ab sofort verfügbar gemacht, die Erinnerungsfunktion soll in der EU in Kürze folgen.
Mit Codex Richtung „Super-App“
Das Codex-Update ist Teil einer größeren Strategie, die die Entwicklung einer „Super-App“ vorsieht, die die Coding-Plattform Codex, den Chatbot ChatGPT und den Atlas-Browser in einer einzigen Desktop-Anwendung kombinieren soll.
Ähnliche agentische Arbeitsfunktionen wie OpenAI bündelt Anthropic bereits in seiner Claude-App mit Cowork und Claude Code. Mit dem jüngsten Codex-Update schließt OpenAI nun in mehreren Bereichen zum großen Konkurrenten auf, setzt aber auch eigene Akzente. Anthropic hatte mit „Computer Use“ bereits im Oktober 2024 den Grundstein gelegt und die Funktion im März 2026 auch in Claude Cowork und Claude Code integriert. OpenAI zieht mit vergleichbaren Funktionen in der Codex-App nach, hebt dabei aber vor allem die parallele Hintergrundarbeit mehrerer Agenten und die Fähigkeit hervor, Aufgaben über längere Zeiträume eigenständig fortzuführen.
Die Ankündigung erfolgte am selben Tag wie die Veröffentlichung von Opus 4.7, Anthropics neuestem Modell.
Weiterlesen nach der Anzeige
(tobe)
-
Künstliche Intelligenzvor 2 Monaten
Top 10: Die beste kabellose Überwachungskamera im Test – Akku, WLAN, LTE & Solar
-
Social Mediavor 2 MonatenCommunity Management und Zielgruppen-Analyse: Die besten Insights aus Blog und Podcast
-
Social Mediavor 2 MonatenCommunity Management zwischen Reichweite und Verantwortung
-
UX/UI & Webdesignvor 3 MonatenEindrucksvolle neue Identity für White Ribbon › PAGE online
-
Entwicklung & Codevor 1 MonatCommunity-Protest erfolgreich: Galera bleibt Open Source in MariaDB
-
Künstliche Intelligenzvor 3 MonatenInterview: Massiver Anstieg der AU‑Fälle nicht durch die Telefon‑AU erklärbar
-
Künstliche Intelligenzvor 2 MonatenSmartphone‑Teleaufsätze im Praxistest: Was die Technik kann – und was nicht
-
Entwicklung & Codevor 3 MonatenKommentar: Entwickler, wacht auf – oder verliert euren Job
