Fehler beheben: Variablen müssen vor ihrer Verwendung vollständig definiert sein
Problem
Im Gegensatz zu MATLAB®, einer dynamisch typisierten Sprache, sind C und C++ statisch typisiert. Das bedeutet, dass der Codegenerator die Typen aller Variablen in Ihrem MATLAB Programmcode ermitteln können muss, um Variablen im generierten Code zu definieren und zuzuweisen. Falls der Codegenerator die Typen einer oder mehrerer Variablen in Ihrem MATLAB Programmcode nicht ermitteln kann, gibt der Codegenerator eine Fehlermeldung mit einem der folgenden Aussagen zurück:
For code generation, all variables must be fully defined before use.
For code generation, all structure fields must be fully defined before use.
Falls sich die Fehlermeldung auf ein Zellenarray oder ein Element eines Zellenarrays bezieht, lesen Sie bitte auch Resolve Issue: Cell Array Elements Must Be Fully Defined Before Use.
Falls sich die Fehlermeldung auf eine Klasse oder eine Klasseneigenschaft bezieht, lesen Sie bitte auch Resolve Error: Class Properties Must Be Fully Defined Before Use.
Mögliche Lösungen
Weisen Sie zum Beheben dieses Problems allen Variablen in Ihrem MATLAB Programmcode auf allen Ausführungspfaden Werte zu. Dazu gehören alle Variablen, die in anderen Datenstrukturen wie beispielsweise Strukturfeldern und Klassen-Eigenschaften enthalten sind. Je nach Ihrem MATLAB Programmcode und der angezeigten Fehlermeldung sollten Sie eine der folgenden Lösungen ausprobieren.
Zuweisen von Werten für alle Variablen auf allen Ausführungspfaden
In bestimmten Fällen kann der Codegenerator nicht feststellen, ob alle Variablen auf allen Ausführungspfaden definiert sind. Sie können beispielsweise eine MATLAB-Funktion undefinedVariableTest erstellen, die eine numerische Eingabe x entgegennimmt und den Absolutwert von x zurückgibt.
function y = undefinedVariableTest(x) %#codegen arguments x (1,1) double end if x == 0 y = 0; elseif x < 0 y = -x; elseif x > 0 y = x; end end
undefinedVariableTest einen Wert für alle Werte von x zurück. Die Codegenerierung für undefinedVariableTest schlägt jedoch fehl, da der Codegenerator keine else-Anweisung findet und daher nicht feststellen kann, dass y auf allen möglichen Ausführungspfaden definiert ist.Um diesen Code für die Codegenerierung geeignet zu machen, müssen Sie den Codegenerator mithilfe einer else-Anweisung dazu veranlassen, zu erkennen, dass y auf allen möglichen Ausführungspfaden definiert ist.
function y = undefinedVariableTest(x) %#codegen arguments x (1,1) double end if x == 0 y = 0; elseif x < 0 y = -x; else y = x; end end
Alternativ können Sie y außerhalb der if-Anweisung einen Platzhalterwert zuweisen.
function y = undefinedVariableTest(x) %#codegen arguments x (1,1) double end y = 0; if x == 0 y = 0; elseif x < 0 y = -x; elseif x > 0 y = x; end end
Zuweisen von Werten für alle Strukturfelder
Sie müssen alle Variablen, die in anderen Datentypen enthalten sind, auf allen Ausführungspfaden definieren, und Sie dürfen die Anzahl oder das Format der Strukturfelder nicht mehr ändern, nachdem die Struktur verwendet wurde. Zudem kann der Codegenerator bei bestimmten Codierungsmustern nicht erkennen, dass alle Variablen, die in einem anderen Datentyp enthalten sind, definiert sind. Versuchen Sie in solchen Situationen, Ihren Code unter Verwendung eines anderen Codierungsmusters umzuschreiben.
In MATLAB Programmcode zur Codegenerierung können Sie einer Struktur keine Felder hinzufügen, nachdem Sie die Struktur gelesen, indiziert oder an eine Funktion übergeben haben. Sie können beispielsweise eine MATLAB-Funktion undefinedFieldTest erstellen, die eine Struktur y zurückgibt. Wenn x größer als 10 ist, definiert undefinedFieldTest das Feld field1 der Struktur s und weist ihm einen Wert zu. Andernfalls definiert undefinedFieldTest die Felder field1 und field2 der Struktur s und weist ihnen Werte zu.
function y = undefinedFieldTest(x) %#codegen arguments x (1,1) double end if x > 10 s.field1 = 11; else s.field1 = 12; s.field2 = 12; end y = s; end
field2 dynamisch zur Struktur s hinzugefügt, falls x kleiner oder gleich 10 ist. Der Codegenerator muss jedoch bereits zum Zeitpunkt der Codegenerierung die Datentypen aller in der Struktur s enthaltenen Felder bestimmen, obwohl der Laufzeitwert von x zu diesem Zeitpunkt noch unbekannt ist. Die Codegenerierung schlägt fehl, da der Codegenerator feststellt, dass das Feld field2 auf einigen Ausführungspfaden Teil der Struktur s ist, auf anderen jedoch nicht.Um diesen Code für die Codegenerierung geeignet zu machen, dürfen Sie die Anzahl oder die Namen der in einer Struktur enthaltenen Felder zur Laufzeit nicht ändern. Definieren Sie alle Felder von s unabhängig vom Laufzeitwert von x.
function y = undefinedFieldTest(x) %#codegen arguments x (1,1) double end s = struct("field1", [], "field2", []); if x > 10 s.field1 = 11; else s.field1 = 12; s.field2 = 12; end y = s; end
Zuweisen von Anfangswerten für alle persistenten Variablen
Sie müssen alle Variablen vom Typ persistent in Ihrem MATLAB Programmcode auf allen Ausführungspfaden definieren. Sie können beispielsweise eine MATLAB-Funktion undefinedPersistentTest erstellen, die die Anzahl ihrer Aufrufe in der Variable count vom Typ persistent speichert. Zum Initialisieren oder Zurücksetzen von count muss undefinedPersistentTest mit dem Argument 0 aufgerufen werden.
function y = undefinedPersistentTest(x) persistent count; if x == 0 count = 0; else count = count + 1; end y = count; end
MATLAB setzt eine persistente Variable, wenn sie zum ersten Mal auftritt, automatisch einer leeren Matrix ([]) gleich. Daher erzeugen Aufrufe von undefinedPersistentTest keinen Fehler, selbst wenn count ein Wert zugewiesen wurde. Der Codegenerator ist jedoch nicht in der Lage, Größe und Typ einer nicht initialisierten persistenten Variablen zum Zeitpunkt der Codegenerierung zu ermitteln. Daher schlägt die Codegenerierung für undefinedPersistentTest fehl, da count nicht für alle Werte von x definiert ist.
Um diesen Code für die Codegenerierung geeignet zu machen, weisen Sie count mithilfe der Funktion isempty einen Wert zu, falls diese Variable nicht definiert ist.
function y = undefinedPersistentTest(x) arguments x (1,1) double end persistent count; if isempty(count) count = 0; end if x == 0 count = 0; else count = count + 1; end y = count; end
Definieren von Variablen ohne Zuweisung
In bestimmten Situationen ist die Definition von Variablen durch Zuweisung im generierten Code sehr aufwändig. Die Definition von Variablen durch Zuweisung kann zudem zu redundanten Kopien von Variablen im generierten Code führen. Mithilfe von coder.nullcopy können Sie den Typ, die Größe und die Komplexität einer Variablen ohne den mit einer Variablenzuweisung verbundenen Aufwand definieren.
Wenn Sie eine Variable mithilfe von coder.nullcopy definieren, können Sie Code generieren, ohne sich an die oben beschriebenen anerkannten Codierungsmuster halten zu müssen. Betrachten Sie beispielsweise die Funktion nullcopyExample. Da diese Funktion coder.nullcopy verwendet, um Speicher für die Klasse MyClass vorab zu reservieren, müssen Sie den Eigenschaften dieser Klasse keine Platzhalterwerte zuweisen.
function y = nullcopyExample(n) %#codegen arguments n (1,1) double {mustBePositive, mustBeInteger} end x = coder.nullcopy(MyClass); for i = 1:n x.prop1 = 1 + i; x.prop2 = x.prop1 + 3; end y = x; end
Hinweis
Verwenden Sie coder.nullcopy mit Vorsicht. Stellen Sie sicher, dass allen Variablen Werte zugewiesen werden. Dies gilt auch für Klasseneigenschaften, Strukturfelder und Array-Elemente. Der Zugriff auf nicht initialisierte Variablen kann zu unvorhersehbaren Ergebnissen führen.