문제 해결: 변수를 사용하기 전에 완전히 정의해야 합니다
문제
동적으로 유형이 지정되는 언어인 MATLAB®과 달리 C와 C++는 정적으로 유형이 지정됩니다. 즉, 코드 생성기가 생성 코드에서 변수를 정의하고 할당하려면 MATLAB 코드에 있는 모든 변수의 유형을 확인할 수 있어야 합니다. 코드 생성기가 MATLAB 코드에서 하나 이상의 변수 유형을 확인할 수 없는 경우 코드 생성기는 다음 문장이 포함된 오류 메시지를 반환합니다.
코드를 생성하려면 모든 변수를 사용 전에 완전히 정의해야 합니다.(For code generation, all variables must be fully defined before use.)
표시되는 오류 메시지가 셀형 배열이나 셀형 배열 요소를 참조하는 경우 Resolve Issue: Cell Array Elements Must Be Fully Defined Before Use 항목을 참조하십시오.
가능한 해결 방법
이 문제를 해결하려면 모든 실행 경로에서 MATLAB 코드에 있는 모든 변수에 값을 할당하십시오. 여기에는 구조체 필드 및 클래스 속성과 같은 다른 데이터 구조체 내에 포함된 모든 변수가 포함됩니다. MATLAB 코드와 표시되는 특정 오류 메시지에 따라 다음 해결 방법 중 하나를 시도해 보십시오.
모든 실행 경로에서 변수에 값 할당하기
경우에 따라 코드 생성기가 모든 실행 경로에서 모든 변수가 정의되어 있는지 확인하지 못할 수 있습니다. 예를 들어 숫자형 입력값 x
를 받아 x
의 절댓값을 반환하는 MATLAB 함수 undefinedVariableTest
를 생성해 보겠습니다.
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
를 호출하면 x
의 모든 값에 대해 하나의 값이 반환됩니다. 그러나 코드 생성기가 else
문을 찾을 수 없어 가능한 모든 실행 경로에서 y
가 정의되어 있는지 확인할 수 없으므로 undefinedVariableTest
에 대한 코드 생성은 실패합니다.이 코드를 코드 생성에 적합하게 만들려면 else
문을 사용하여 코드 생성기가 가능한 모든 실행 경로에서 y
가 정의되어 있음을 인식하도록 합니다.
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
또는 if
문 외부에서 y
에 더미 값을 할당합니다.
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
모든 구조체 필드와 클래스 속성에 값 할당하기
모든 실행 경로에서 다른 데이터형 내에 포함된 모든 변수를 정의해야 하며, 구조체나 클래스가 사용된 후에는 구조체 필드나 클래스 속성의 개수나 형식을 변경할 수 없습니다. 또한 특정 코딩 패턴의 경우 코드 생성기가 다른 데이터형 내에 포함된 변수들이 모두 정의되어 있는지 인식할 수 없습니다. 이 경우 다른 코딩 패턴을 사용하여 코드를 재작성해 보십시오.
구조체 필드. 코드 생성을 위한 MATLAB 코드에서 구조체를 읽거나, 구조체를 인덱싱하거나, 구조체를 함수에 전달한 후에는 구조체에 필드를 추가할 수 없습니다. 예를 들어 구조체 y
를 반환하는 MATLAB 함수 undefinedFieldTest
를 생성해 보겠습니다. x
가 10보다 크면 undefinedFieldTest
는 구조체 s
의 필드 field1
을 정의하고 값을 할당합니다. 그렇지 않으면 undefinedFieldTest
는 구조체 s
의 field1
과 field2
를 정의하고 값을 할당합니다.
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
x
가 10 이하이면 구조체 s
에 필드 field2
가 동적으로 추가됩니다. 그러나 x
의 런타임 값을 알 수 없는 경우, 코드 생성기는 구조체 s
에 포함된 모든 필드의 유형을 코드 생성 시점에 확인해야 합니다. 필드 field2
가 몇몇 실행 경로에서는 구조체 s
의 일부이지만 다른 실행 경로에서는 그렇지 않음을 코드 생성기가 감지하기 때문에 코드 생성이 실패합니다.이 코드를 코드 생성에 적합하게 만들려면 런타임 시점에 구조체에 포함된 필드의 개수나 이름을 변경하지 마십시오. x
의 런타임 값과 관계없이 s
의 모든 필드를 정의하십시오.
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
클래스 속성. 루프에서 클래스 속성에 값을 할당하는 특정 코딩 패턴의 경우 코드 생성기는 모든 속성이 정의되어 있는지 인식할 수 없습니다. 예를 들어 양의 정수 입력 n
을 받아 MyClass
클래스의 인스턴스를 반환하는 MATLAB 함수 undefinedPropTest
를 생성해 보겠습니다. MyClass
클래스에는 prop1
과 prop2
라는 두 가지 속성이 있습니다. 함수 undefinedPropTest
는 for
루프 내에서 반환된 myClass
객체의 prop1
과 prop2
에 값을 할당합니다.
function y = undefinedPropTest(n) %#codegen arguments n (1,1) double {mustBePositive, mustBeInteger} end x = MyClass; for i = 1:n x.prop1 = 1 + i; x.prop2 = x.prop1 + 3; end y = x; end
undefinedPropTest
는 허용되는 모든 n
값에 대해 하나의 MyClass
인스턴스를 반환합니다. 그러나 코드 생성기는 undefinedPropTest
가 모든 n
값에 대해 prop1
과 prop2
에 값을 할당하는지 확인할 수 없으므로 undefinedPropTest
에 대한 코드 생성이 실패합니다.이 코드를 코드 생성에 적합하게 만들려면 for
루프 앞에서 MyClass
의 모든 속성에 더미 값을 할당하십시오.
function y = undefinedPropTest(n) %#codegen arguments n (1,1) double {mustBePositive, mustBeInteger} end x = MyClass; x.prop1 = 0; x.prop2 = 0; for i = 1:n x.prop1 = 1 + i; x.prop2 = x.prop1 + 3; end y = x; end
모든 영속 변수에 초기값 할당하기
모든 실행 경로에서 MATLAB 코드에 있는 모든 persistent
변수를 정의해야 합니다. 예를 들어 persistent
변수 count
에 호출된 횟수를 저장하는 MATLAB 함수 undefinedPersistentTest
를 생성해 보겠습니다. count
를 초기화하거나 재설정하려면 인수 0
을 사용하여 undefinedPersistentTest
를 호출해야 합니다.
function y = undefinedPersistentTest(x) persistent count; if x == 0 count = 0; else count = count + 1; end y = count; end
MATLAB은 영속 변수를 처음으로 발견하면 자동으로 영속 변수를 빈 행렬([]
)로 설정합니다. 따라서 count
에 값이 지정된 경우에 undefinedPersistentTest
를 호출해도 오류가 발생하지 않습니다. 그러나 코드 생성기는 초기화되지 않은 영속 변수의 크기와 유형을 코드 생성 시점에 확인할 수 없습니다. 따라서 count
가 x
의 모든 값에 대해 정의되지 않았으므로 undefinedPersistentTest
에 대한 코드 생성이 실패합니다.
이 코드를 코드 생성에 적합하게 만들려면 count
가 정의되지 않은 경우 isempty
함수를 사용하여 해당 변수에 값을 할당하십시오.
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
할당 없이 변수 정의하기
특정 상황에서는 생성 코드에서 할당을 통해 변수를 정의하는 것과 관련된 오버헤드가 상당할 수 있습니다. 할당을 통해 변수를 정의하면 생성 코드에 변수의 복사본이 중복되어 나타날 수도 있습니다. 변수 할당의 오버헤드 없이 변수 유형, 크기, 실수/복소수 여부를 정의하려면 coder.nullcopy
를 사용하십시오.
coder.nullcopy
를 사용하여 변수를 정의하면 위에서 설명한 일반적으로 인정되는 코딩 패턴을 따르지 않고도 코드를 생성할 수 있습니다. 예를 들어 함수 nullcopyExample
을 살펴보겠습니다. 이 함수는 coder.nullcopy
를 사용하여 MyClass
클래스에 대한 메모리를 사전할당하므로 이 클래스의 속성에 더미 값을 할당할 필요가 없습니다.
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
참고
주의하여 coder.nullcopy
를 사용하십시오. 클래스 속성, 구조체 필드, 배열 요소를 포함한 모든 변수에 값을 할당하는지 확인해야 합니다. 초기화되지 않은 변수에 액세스하면 결과가 예측 불가능해질 수 있습니다.