Attribute (auch Pragmas genannt) sind Compiler-Anweisungen, die mit @ beginnen und vor einer Deklaration stehen. Sie steuern Optimierungen, Sicherheits-Verifikation, Speicherlayout und FFI-Verhalten. Attribute verändern nie die Semantik des Programms für korrekte Eingaben — sie sind Zusatzinformationen für den Compiler, nicht für den Laufzeit-Interpreter.
→ Compiler-Flags (CLI) · DO-178C Compliance · Energy-Aware Modell · FFI – C-Interop
Alle Attribute auf einen Blick:
| Attribut | Ziel | Kategorie | Beschreibung |
|---|---|---|---|
@dal(A–D) | Unit, Fn | Safety | Design Assurance Level nach DO-178C |
@flight_crit | Unit, Fn | Safety | Strikte Luftfahrt-Regeln |
@critical | Fn | Safety | Als kritisch markieren |
@integrity(mode: …) | Fn (scrubbed auch vor unit) | Safety | mode: scrubbed (Sweep über die geladenen Codeseiten) oder mode: software_lockstep (Rückgabeausdruck doppelt gerechnet) |
@redundant | Variable | Safety | Triple Modular Redundancy (TMR) |
@stack_limit(N) | Fn | Safety | Maximaler Stack-Verbrauch in Bytes |
@wcet(N) | Fn | Safety | Worst-Case Execution Time in Zyklen |
@energy(1–5) | Unit, Fn | Performance | Energy-Aware-Backend-Level |
@packed | Struct | Layout | Struct-Padding unterdrücken |
@align(N) | Variable | Layout | Allokations-Alignment in Bytes |
@big_endian | Struct-Feld | Layout | Feld liegt in Network Byte Order; Zugriffe erzeugen einen Byte-Swap. @little_endian gibt es am Feld nicht — siehe unten |
@volatile | Variable | FFI | Speicherzugriff nicht wegoptimieren |
@description / @author / @copyright / @version | Modulkopf | Doku | Beschreibende Angaben vor unit/import |
Jedes Attribut einzeln übersetzt, jeweils gegen dasselbe Programm ohne Attribut verglichen (Rückgabewert, Meldungen, Größe des Erzeugnisses).
| Attribut | Angenommen | Wirkung, gemessen |
|---|---|---|
@dal(A)…@dal(D) | ja | Warnung: „@dal: die Zusicherung wird vom Compiler NICHT nachgewiesen„. Erzeugnis unverändert. @dal(Z) bricht ab: „Stufe muss A, B, C oder D sein“ |
@flight_crit | ja, ohne Warnung | Erzeugnis wächst (4243 → 4327 Byte) — das Attribut schaltet tatsächlich etwas frei (FPU-Traps, #1140) |
@critical | ja | Warnung: wird nicht nachgewiesen. Erzeugnis unverändert |
@integrity(mode: scrubbed), @integrity(mode: software_lockstep) | ja | wird nachgewiesen (seit 1.1.15A): Hashtabelle METASAF2 plus SIGALRM-Sweep bzw. doppelt gerechneter Rückgabeausdruck. Nur x86-64. Die Kurzformen ohne mode: und der Modusname memory_scrubbing werden abgewiesen |
@redundant | ja | Wirkt: --verify-tmr meldet „1 @redundant-Variable(n), 1 gevotete® Lesezugriff(e), 0 am Voter vorbei„ |
@stack_limit(N) | ja | Wird nachgewiesen und bricht ab: @stack_limit(8) an einer Funktion mit 16-Byte-Rahmen → „@stack_limit(8) verletzt — der Rahmen belegt 16 Byte“. Gezählt wird der Rahmen, nicht statisch abgelegte Felder |
@wcet(N) | ja | Wird nachgewiesen: @wcet(1) an einer Schleife mit 1000 Durchläufen → „@wcet(1) verletzt — der Rumpf laeuft bis zu 1000 Iterationen„. Ein Aufruf ohne Schranke bricht ebenfalls ab: „PrintLn liegt nicht in dieser Einheit und traegt keine Schranke“ |
@energy(1–5) | ja | Übersetzt; Erzeugnis in diesem Prüffall unverändert |
@packed | ja | Wirkt: struct{int16,int8,int16} misst 5 statt 6 Byte |
@align(N) | ja | Übersetzt an einer lokalen Variablen |
@big_endian | ja, an jedem Feld | Byte-Swap bei jedem Zugriff |
@little_endian | nein | Parse error, auch am ersten Feld (#1864) |
@volatile | ja | Übersetzt an einer lokalen Variablen |
@description, @author, @copyright, @version | ja | Übersetzt; reine Metadaten |
Die Warnung bei@dal,@criticalund@integrityist die ehrliche Auskunft, kein Mangel. Der Compiler sagt damit: das Attribut dokumentiert eine Zusicherung, er prüft sie nicht. Nachgewiesen werden nur@stack_limit,@wcetund — mit--verify-tmr—@redundant. Wer die drei anderen in einem Zertifizierungsnachweis führt, braucht dafür ein Verfahren außerhalb des Compilers.
Externe Funktionen werden ohne Attribut deklariert — mit dem Schlüsselwort extern (siehe FFI).
Diese Attribute gibt es nicht. Frühere Fassungen dieser Seite führten sie mit eigenen Abschnitten; der Compiler weist jeden unbekannten Attributnamen seit #1099 mitunbekanntes Attributab:
@inline·@noinline·@no_opt·@parallel·@section(„name“)·@at(N)·@stdcall·@variadic·@allow_unsafe
@exportgehört nicht in diese Liste — es existiert und wird anextern fnangenommen. (Issue #1247)
Damit entfällt auch die Vorstellung, Inlining oder Vektorisierung ließen sich per Annotation steuern — das Backend entscheidet das selbst, beeinflussbar allein über@energyund–target-energy.
@allow_unsafehätteunsafe-Blöcke freigeben sollen; auch die gibt es nicht (undefined symbol '\unsafe'\).
Attribute für sicherheitskritischen und zertifizierungspflichtigen Code:
Legt das Design Assurance Level nach DO-178C fest. Beeinflusst, welche Lint-Prüfungen aktiv sind und ob bestimmte Sprachfeatures verboten werden.
@dal(A)
unit flight_control;
@dal(B)
fn ProcessSensorData(raw: int64): int64 { ... }
| Level | Bedeutung | Einschränkungen |
|---|---|---|
@dal(A) | Katastrophaler Ausfall möglich | Kein unbounded loop, exhaustive match |
@dal(B) | Gefährlicher Ausfall möglich | Unbounded loops mit Warnung |
@dal(C) | Größerer Ausfall möglich | Empfehlungen, keine harten Verbote |
@dal(D) | Geringfügiger Ausfall möglich | Nur Dokumentation, keine Compiler-Einschränkungen |
Aktiviert den strengsten Kompilierungsmodus für sicherheitskritische Funktionen:
@flight_crit
@dal(A)
@stack_limit(512)
fn ComputeFlightPath(state: int64): FlightCommands { ... }
Wirkung zur Laufzeit: Der Prolog der Funktion schaltet die SSE-Ausnahmen für invalid (NaN) und divide-by-zero frei und sichert MXCSR, der Epilog stellt den alten Wert wieder her. Eine entstehende NaN oder Inf löst damit SIGFPE aus statt still weiterzurechnen; der mitgegebene Handler meldet panic: FPU-Ausnahme (NaN/Inf oder Division durch 0) unter @flight_crit in `NAME` und endet mit 134. Die Reichweite ist dynamisch: MXCSR ist Thread-Zustand, der Trap gilt also auch für alles, was die Funktion ruft, bis sie zurückkehrt. Überlauf, Unterlauf und Ungenauigkeit bleiben maskiert.
Impliziert automatisch:
@energy(1) — kein aggressives Unrolling, keine SIMD-Spekulationnew/alloc im Rumpf@stack_limitmatch über alle Enum-Werte (kein default in DAL-A)Das Speicherverbot ist seit lyxc 1.0.21B durchgesetzt (#1529) und meldet, gemessen mit 1.1.3I:
sema error: Speicheranforderung unter @flight_crit nicht erlaubt 'alloc'
sema error: new ist unter @flight_crit nicht erlaubt — der Speicher muss ausserhalb angelegt und hereingereicht werden
sema error: lokales Feld unter @flight_crit nicht erlaubt (es entsteht per mmap, nicht auf dem Stapel)
Die Prüfung reicht seitlyxc 1.1.4Aüber Aufrufgrenzen hinweg (#1701, nachgemessen mit 1.1.11B). Ruft eine@flight_crit-Funktion einen Helfer, derallocbenutzt, meldet der Compiler:
sema error: Speicheranforderung in einer Funktion, die aus einer @flight_crit-Funktion gerufen wird 'alloc'
Die Prüfung folgt der Aufrufkette mit Zyklusschutz — auch über zwei und mehr Ebenen — und kennt nebennew/allocauch die allozierenden Zeichenketten-Funktionen (IntToStr,StrConcat,StrNew,StrCopy,StrSub,StrTrim,FloatToStr).
Ein Aufruf über einen Funktionszeiger wird jetzt rundheraus abgewiesen —indirekter Aufruf unter @flight_crit nicht erlaubt — das Sprungziel steht erst zur Laufzeit fest und laesst sich nicht nachweisen. Was sich nicht nachweisen lässt, gilt damit nicht mehr als unauffällig.
Kompatibel mit @energy(2) wenn explizit annotiert (zulässig für DAL-B):
@flight_crit
@energy(2) // energy-Barriere: überschreibt das implizite @energy(1)
@dal(B)
fn FilterAltitude(raw: f64): f64 { ... }
Aktiviert Laufzeit-Integritätsprüfung. Zwei Modi:
// Modus 1: Memory Scrubbing (periodischer CRC32-Sweep des Code-Segments)
@integrity(mode: scrubbed, interval: 100)
unit nav.core;
// Modus 2: Software Lockstep (duplizierte ALU-Operationen, Vergleich vor Return)
@integrity(mode: software_lockstep)
@dal(A)
fn ComputeHeading(imu: int64): f64 { ... }
| Parameter | Typ | Beschreibung |
|---|---|---|
mode: scrubbed | – | Vorgesehen: CRC32-Sweep des Code-Segments alle interval ms |
mode: software_lockstep | – | Vorgesehen: Berechnungen doppelt ausführen, Ergebnis vergleichen |
interval: N | int (ms) | Sweep-Intervall für scrubbed-Modus |
@integrityhat heute keine Wirkung (#1878). Der Compiler nimmt das Attribut an, meldetwarning: @integrity: die Zusicherung wird vom Compiler NICHT nachgewiesen— und erzeugt ein byte-gleiches Programm (4243 Byte mitscrubbed, mitsoftware_lockstepund ohne Attribut, gemessen mit 1.1.14A). Kein Sweep, keine doppelte Berechnung, kein Recovery-Handler.
Auch die.meta_safe-Sektion entsteht dadurch nicht — die gibt es nur mit--meta-safeauf der Kommandozeile.
Ursache im Quelltext:src/ir/ir_safety.lyxträgt die Pragma-Logik, wird aber nirgends importiert oder gebaut. Das erklärt, warum@integrity,@criticalund@dalallesamt nur warnen, während@stack_limitund@wcet— die im Codegen sitzen — tatsächlich nachgewiesen werden.
→ Details: Memory Scrubbing · Software Lockstep
Speichert eine Variable dreifach im RAM (Sektionen .tmr_a, .tmr_b, .tmr_c). Jeder Lesezugriff führt einen Mehrheitsentscheid durch; ein korrumpiertes Exemplar wird automatisch repariert.
@redundant
var flight_mode: int64 := 0;
@redundant
var altitude_m: f64 := 0.0;
@x liefert die Adresse einer Kopie und umgeht damit den Voter — ein Schreibzugriff darüber geht beim nächsten Mehrheitsentscheid verloren. Der Compiler meldet das: unter --verify-tmr als Fehler, sonst als Warnung--verify-tmr druckt die Bilanz (Variablen, gevotete Lesezugriffe, dreifache Schreibzugriffe, Umgehungen) und endet mit Exit 1, sobald ein Zugriff am Voter vorbeigeht→ Details: TMR
Setzt ein hartes Limit für den Stack-Verbrauch einer Funktion in Bytes. Wird bei jeder Übersetzung geprüft — ein Flag dafür gibt es nicht und ist nicht nötig. Geprüft werden zwei Dinge: die Rahmengröße der Funktion selbst gegen die Schranke, und dass die Funktion nicht rekursiv ist (auch nicht indirekt über den Aufrufgraphen) — ohne nachweisbare Aufruftiefe wäre der Verbrauch unbeschränkt. Beides sind harte Fehler. Nicht erfasst: der Verbrauch der aufgerufenen Funktionen entlang der Aufrufkette und dynamisch angeforderter Speicher. Zu beachten: ein [N]int64 liegt nicht im Rahmen — Arrays bekommen einen Heap-Block, der Rahmen wächst nur um 8 Byte je Variable.
@stack_limit(2048)
fn ParsePacket(buf: pchar, len: int64): bool { ... }
@stack_limit(128)
@flight_crit
fn SysTick_Handler(): void { ... } // ISR: sehr wenig Stack erlaubt
Gibt die maximal erlaubte Worst-Case Execution Time in Iterationen an — nicht in CPU-Zyklen. Eine Zyklenzahl bräuchte ein Mikroarchitekturmodell; Iterationen sind das, was sich am Syntaxbaum abzählen lässt.
@wcet(200)
@dal(A)
fn ReadIMU(buf: int64): void { ... }
@wcet(500)
fn FilterAltitude(raw: f64): f64 { ... }
B * (1 + I) bei — zwei geschachtelte Zehnerschleifen ergeben 110for … to/downto und for i in a..b mit literalen Grenzen, for i in range(A, B), while © limit(N) und while (i < C) mit literalem Startwert, konstanter Grenze und genau einer Fortschaltung i := i + K, K > 0@wcet-Funktion ein Fehler, kein stiller Durchlass: berechnete Schleifengrenzen, repeat/until, das C-artige for, Rekursion (auch indirekt) und der Aufruf einer Funktion ohne eigene Schranke — importierte Funktionen eingeschlossen, PrintLn also auch--wcet-Flag gibt es nicht — der Nachweis läuft bei jeder Übersetzung. Für den Aufrufgraphen --call-graph verwenden
Steuert das Energy-Aware-Backend für diese Funktion. Es überschreibt das globale –target-energy-Level und erzeugt eine Energy-Barriere — inlinierte Aufrufer übernehmen das Level dieser Funktion nicht.
Die Vorrangregel lautet seit lyxc 1.0.15C:
@energy(N) an der Funktion@energy(N); als Direktive im Quelltext–target-energy=N auf der Kommandozeile
Der Quelltext schlägt also das Flag. Zu beachten: Funktionen ohne Attribut — auch die aus importierten Units — folgen weiterhin dem Flag; ein Programm ist deshalb mit und ohne –target-energy nur dann byteidentisch, wenn jede beteiligte Funktion annotiert ist.
@energy(1)
fn IdleSensor(): void { ... } // Batterie-optimiert
@energy(5)
fn MatMulKernel(a: int64, b: int64, out: int64): void { ... } // Max-Performance
→ Details und Level-Tabelle: Energy-Aware Modell
Unterdrückt Alignment-Padding in einer Struct-Definition. Felder folgen ohne Lücken aufeinander. Notwendig für Hardware-Register-Maps, Netzwerk-Paket-Header, binäre Protokolle.
Es gibt zwei gleichwertige Schreibweisen — das Attribut vor der Deklaration oder das Schlüsselwort packed vor struct:
@packed
type CANFrame = struct {
id: int32; // 4 Bytes (11-Bit-ID + Flags)
dlc: int8; // 1 Byte (Data Length Code)
data: int64; // 8 Bytes (Nutzdaten)
}
type IpFragment = packed struct {
ident: int16;
frag_off: int16;
ttl: int8;
}
Felder stehen ohne var und die Struktur braucht die Form type Name = struct. Ein alleinstehendes class Name { … } wie in C++ oder Java weist der Compiler mit unexpected top-level token ab.
Die Wirkung lässt sich mit sizeof nachmessen:
type Locker = struct { a: int16; b: int8; c: int16; }
type Dicht = packed struct { a: int16; b: int8; c: int16; }
fn main(): int64 {
PrintLn("struct = ", IntToStr(sizeof(Locker)));
PrintLn("packed struct = ", IntToStr(sizeof(Dicht)));
return 0;
}
struct = 6
packed struct = 5
Fünf Nutzbytes gegen sechs: die reguläre Ausrichtung legt jedes Feld auf ein Vielfaches seiner eigenen Breite (int16 auf 2, int8 auf 1) — a auf 0, b auf 2, ein Füllbyte, c auf 4. Das entspricht dem Speicherbild eines C-Structs. Bis 1.0.21A lag jedes Feld auf einer 8-Byte-Grenze (#1516), derselbe Struct maß dort 18 Byte; ältere Fassungen dieser Seite zeigen diese Zahl. packed bleibt für Protokollköpfe richtig, wo auch das eine Füllbyte stört — nachgemessen mit 1.1.14A.
Markiert ein Struct-Feld als Big-Endian (Network Byte Order). Lese- und Schreibzugriffe auf das Feld erzeugen automatisch Byte-Swap-Instruktionen (bswap auf x86_64, rev auf ARM64).
type IpHeader = packed struct {
@big_endian ethertype: int16; // z. B. 0x0800 für IPv4
@big_endian total_len: int16;
@big_endian ident: int16;
@big_endian frag_off: int16;
ttl: int8;
protocol: int8;
@big_endian checksum: int16;
};
Das Attribut steht direkt vor dem Feldnamen — ohne var und ohne Offset-Angabe. Für ein festes Speicherbild sorgt packed struct (→ Datentypen).
Seit lyxc 1.0.15G schreibt eine Feldzuweisung genau so viele Bytes, wie das Feld breit ist (mov [rax+off], sil / si / esi bei 1, 2 und 4 Byte) — Nachbarfelder bleiben unberührt, in gepackten wie in ungepackten Strukturen. Die Reihenfolge der Zuweisungen spielt damit keine Rolle mehr.
int8 ist byteorder-neutral)1, liefert das @big_endian-Feld 16777216 (0x01000000).@little_endianist am Struct-Feld nicht schreibbar (#1864, gemeldet aus dieser Prüfung). Der Name steht zwar in der Attributliste des Parsers und im Hilfetext, wird an einer Feldposition aber nie angenommen:
type K = struct { @little_endian a: int32; // Parse error at line 2: expected IDENT, got @ '@' b: int32; }
Mit@big_endianan derselben Stelle übersetzt dasselbe Programm. Little-Endian ist auf x86-64 und ARM64 ohnehin die Speicherordnung — wer sie ausdrücklich hinschreiben will, kann es derzeit nicht. Frühere Fassungen dieser Seite führten beide Namen gleichrangig. Gemessen mit 1.1.14A.
Die frühere Schreibweise@at(0) @big_endian var feld: u16;ist in keinem Teil gültig.@atexistiert nicht (unbekanntes Attribut), und die Kombination scheitert schon am Parser (expected IDENT, got @). Auchvargehört nicht in eine Struct-Deklaration.
@big_endianselbst arbeitet korrekt und braucht keine Offset-Angabe. (Issue #1247)
===== Ressourcen einbetten =====
Seit #1961 lassen sich Dateien ins Erzeugnis einbetten — das Gegenstück zu Delphis .res. Es gibt zwei Wege, und sie beantworten verschiedene Fragen.
==== @resource(„name“, „pfad“) ====
Auf Unit-Ebene. Trägt die Datei in eine benannte Tabelle ein, die zur Laufzeit durchsucht und aufgelistet werden kann:
unit main;
@resource("splash", "assets/splash.lyxi");
import std.res;
fn main(): int64 {
var bild: pchar := ResFind("splash");
var n: int64 := ResLen("splash");
return 0;
}
Der Pfad wird relativ zur Quelldatei aufgelöst. Fehlt die Datei, bricht die Übersetzung ab (error: @resource: Datei nicht lesbar: …) — eine fehlende Ressource fällt beim Bauen auf, nicht beim Kunden. Die Zugriffsfunktionen stehen in std.res.
<WRAP center round important 90%>
@resource gibt es bisher nur mit --target=x86_64. Auf dem IR-Weg (lyxos, arm64, riscv, xtensa) bricht die Übersetzung mit einer Meldung ab, die auf #1968 verweist: die Tabelle besteht aus Zeigern in den Datenbereich, und dort gibt es bisher nur die nullterminierte Zeichenkettentabelle.
</WRAP>
==== @embed(„pfad“) und @embed_len(„pfad“) ====
Im Ausdruck, aufgelöst zur Übersetzungszeit:
var s: pchar := @embed("assets/hilfe.txt");
var n: int64 := @embed_len("assets/hilfe.txt");
Der kürzere Weg, wenn genau eine Datei an genau einer Stelle gebraucht wird — dafür ohne Namen, ohne Auflisten und ohne Auswahl zur Laufzeit. Auf den IR-Zielen ist das der einzige Weg, und dort für Textdateien.
[N]uint8-Feld: Lyx legt Felder mit acht Byte je Element ab, auch bei uint8. Ein eingebettetes 1-MB-Bild bräuchte damit 8 MB im Erzeugnis. Die Bytes liegen deshalb gepackt im Datensegment, und @embed liefert die Adresse. Gelesen wird mit peek8.
===== FFI-Attribute =====
Attribute für die Interoperabilität mit externen Bibliotheken und C-Code:
==== extern (Schlüsselwort, kein Attribut) ====
Externe Funktionen werden mit dem Schlüsselwort extern deklariert — ein Attribut @extern gibt es nicht.
@capabilities([system.exit, system.memory.heap, system.time])
import std.io;
extern fn time(t: int64): int64 link "libc.so.6";
fn main(): int64 {
PrintLn(IntToStr(time(0)));
return 0;
}
link-Klausel ist Pflicht und nennt die Bibliothek mit ihrem vollständigen Dateinamen („libc.so.6“, nicht „c“)@capabilities wird die Deklaration abgewiesen (extern fn: unbekanntes FFI-Symbol erfordert @capabilities([…])), ebenso ein Symbol, das nicht in der Zuordnung steht.Dielink-Klausel ist seit lyxc 1.0.17C Pflicht (#1179). Fehlt sie, bricht schon der Parser ab:extern fn: die link-Klausel fehlt. Bis 1.0.16x übersetzte die Deklaration auch ohne, das Symbol wurde nie gebunden und der Aufruf lieferte still0— bei C-Funktionen ein plausibler Wert, der Fehler fiel damit kaum auf. Die eigene Standardbibliothek trug 33 solcher Deklarationen (std.time.Now()gab 0,env_getimmer„“,abort()beendete nichts); alle sind ersetzt.
Ein falscher Bibliotheksname wird weiterhin nicht zur Übersetzungszeit gemeldet — den vollständigen Dateinamen angeben („libc.so.6“, nicht„c“) und einen neuen FFI-Aufruf einmal gegen einen bekannten Wert prüfen.
→ Details: FFI – C-Interop · Capabilities
==== @align(N) ====
Setzt das Allokations-Alignment einer Variablen in Bytes. Wirkt auf array- und heap-gestützte lokale Variablen; bei skalaren Stack-Variablen ohne Bedeutung.
fn main(): int64 {
@align(64) var puffer: array<int64> := [1, 2];
return puffer[0];
}
==== @volatile ====
Verhindert, dass der Compiler Lese- und Schreibzugriffe auf eine Variable wegoptimiert, zwischenspeichert oder umordnet. Essentiell für Memory-Mapped I/O und ISR-Kommunikation.
@volatile var uart_data_reg: int64 := 0x40011004; // UART-Datenregister-Adresse
@volatile var isr_flag: int64 := 0; // Gesetzt von ISR, gelesen von Main
fn WaitForData(): void {
while (isr_flag == 0) limit(1000000) { } // Ohne @volatile würde der Compiler dieses Loop wegoptimieren
isr_flag := 0;
}
Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).
Letzte Aktualisierung: 2026-09-05 (#1961, nachgemessen mit lyxc 1.2.2D) — Abschnitt „Ressourcen einbetten„ ergänzt: @resource (benannte Tabelle, nur x86-64) und @embed/@embed_len (zur Übersetzungszeit aufgelöst).
Vorherige letzte Aktualisierung: 2026-09-05 (#1908, gemessen mit lyxc 1.1.18A) — @integrity-Zeilen auf den gemessenen Stand gezogen: seit 1.1.15A nachgewiesen (kein „Erzeugnis unverändert“ mehr), Prüfstandszeile von den ungültigen Kurzformen memory_scrubbing/software_lockstep auf mode: scrubbed bzw. mode: software_lockstep berichtigt.
Vorherige letzte Aktualisierung: 2026-08-30 — alle 14 Attribute einzeln gegen lyxc 1.1.14A durchgemessen (siehe Abschnitt „Prüfstand„); struct-Größe im @packed-Beispiel berichtigt (6 statt 18, #1516 behoben); @little_endian am Feld als nicht schreibbar belegt und gemeldet (#1864).