EDIT:As of Matlab 2015b, Coder ma teraz błąd wykonania kontroli jako opcja (od release notes Matlab):
W R2015b, generowane jednostkowe biblioteki i pliki wykonywalne mogą wykrywać błędy i Runtime taki raport jako indeksowanie tablic out-of-bounds. W poprzednich wersjach tylko wygenerowane przez MEX wykryte i zgłoszone błędy w czasie wykonywania: .
Domyślnie wykrywanie błędów uruchamiania jest włączone dla MEX. Domyślnie wykrywanie błędów podczas wykonywania jest wyłączone dla autonomicznych bibliotek i plików wykonywalnych.
Aby umożliwić wykrywanie błędów w czasie wykonywania samodzielnych dla bibliotek i plików wykonywalnych:
W wierszu poleceń, należy użyć właściwości konfiguracji kod RuntimeChecks
.
cfg = coder.config ('lib'); % lub 'dll' lub 'exe'
cfg.RuntimeChecks = true;
Codegen -config cfg myfunction
Korzystanie z aplikacji MATLAB Coder, w ustawieniach Build Project, na karcie debugowania, wybierz sprawdzić Generowanie sprawdza błąd czasu pudełko.
Wygenerowane biblioteki i pliki wykonywalne używają fprintf do pisania komunikatów o błędach do stderr i przerywania w celu zakończenia aplikacji. Jeśli nie są dostępne fprintf i abort , musisz je podać. Komunikaty o błędzie są w języku angielskim.
Zobacz Run-Time Error Detection and Reporting in Standalone C/C++ Code i Generate Standalone Code That Detects and Reports Run-Time Errors.
odpowiedź oryginalny: odpowiedź w komentarzach dotyczących deklarowania klasy podklasy z podwójnym którym sposób subsref jest przeciążony zabronić uprawy byłyby Dobrym sposobem, aby to zrobić.
Innym prostym sposobem na to jest posypywanie poleceń assert
w całym kodzie (w każdej iteracji pętli lub na dole funkcji), aby potwierdzić, że rozmiar nie zwiększył się nad przydzielonym rozmiarem.
Na przykład, jeśli miał kod w formacie:
x = zeros(a,1)
x(a+1) = 1
... lots of other operations
if coder.target('MATLAB')
assert(isequal(size(x), [a,1]), 'x has been indexed out of bounds')
end
byłoby to niech masz twierdzenie powiedzie się, jeśli jakakolwiek wartość przypisano że rozszerzył wachlarz.
Aby uczynić to nieco bardziej uporządkowanym, możesz nawet utworzyć funkcję, która obejmie zaznaczone wszystkie zmienne, które Cię interesują, ponownie owijając instrukcję coder.target
. Potem możesz posypać to całym kodem.
To nie jest tak eleganckie jak przeciążenie podwójnej klasy, ale z drugiej strony nie dodaje żadnego dodatkowego obciążenia do skompilowanego kodu. Nie spowoduje to również błędów dokładnie w momencie przekroczenia limitu, ale da pewność, że kod działa dobrze w różnych sytuacjach.
Innym sposobem na zwiększenie pewności zleceń jest samodzielne sprawdzenie przypisania zlecenia w sytuacjach, w których może to być właściwe. Typowy problem, który widziałem w zadaniu, ma coś takiego. Mamy przydzieloną tablicę i kopiujemy dane z innej tablicy z przypisaniem wektora. Na przykład, należy rozważyć następującą sytuację:
t = char(zeros(5,7)); % Allocate a 5 by 7 char array
tempstring = 'hello to anyone'; % Here's a string we want to put into it.
t(1, 1:numel(tempstring)) = tempstring; % A valid assignment in MATLAB
>> size(t)
ans =
5 15
Uh oh, co dokładnie jesteś zaniepokojony w pytaniu działo się: tablica t
została automatycznie zmieniany podczas cesji, która działa w MATLAB-ie, ale w Coder utworzony kod spowoduje błąd segfault lub MEX. Alternatywą jest użycie siły funkcji end
zachować zadanie schludny Jeśli mamy zmienić przypisanie do (ale obcięty.):
t(1,1:min(end,numel(tempstring))) = tempstring(1:size(t, 2));
Wielkość t
pozostanie niezmieniona, ale przypisanie zostanie obcięty. Korzystanie z end
umożliwia sprawdzanie granic podczas przypisywania. W niektórych sytuacjach może to być dobry sposób na rozwiązanie tego problemu i da pewność, że granice nigdy nie zostaną przekroczone, ale oczywiście w niektórych sytuacjach jest to bardzo niepożądane (i nie spowoduje wyświetlenie komunikatów o błędach w MATLAB.)
Innym przydatnym narzędziem, które MATLAB zapewnia, jest sam edytor. Jeśli użyjesz znacznika %#codegen
w swoim kodzie, to zasygnalizuje to narzędzie do sprawdzania składni edytora, aby podkreślić różne problemy z generowaniem kodu, w tym miejsca, w których oczywiście zwiększasz rozmiar tablicy przez indeksowanie. Nie może to złapać każdej sytuacji, ale jest to dobra pomoc.
ostatnia uwaga. Jak wspomniano w pytaniu, plik MEX wygenerowany przez program Coder da ci błąd "Indeks przekracza wymiary matrycy" w momencie przypisania i z gracją wyjdzie, a nawet powie ci pierwotny wiersz kodu, w którym wystąpił błąd. Biblioteka C wygenerowana z kodera nie ma takiego miłego zachowania lub sprawdzania granic i całkowicie się odłączy bez żadnej diagnostyki.Odpowiedź pośrednia polega na wykonaniu dokładnie tego, co robisz, czyli na uruchomieniu kodu jako MEX. To nie jest pomocne dla twojego pytania (jak mówisz, przebudowa MEX-a może zająć trochę czasu), ale dla tych z nas, którzy kodują zimny, okrutny świat zewnętrznego kodu C, pośredni test na to, by móc uruchomić MEX, aby znaleźć te błędy to ratownik.
Najważniejsze jest to, że jest to rozbieżność między kodowaniem MATLAB i Coder generowanym przez kod C, co może być źródłem znaczących problemów. W moim własnym kodzie, jestem bardzo ostrożny z dostępem do tablicy i wzrostem właśnie z tego powodu. To obszar, w którym chciałbym zobaczyć ulepszenie samego narzędzia Coder, ale są sposoby, aby być bardzo ostrożnym przy pisaniu kodu MATLAB skierowanego do Coder'a.
Interesujące pytanie. "_Automatyczna zmiana rozmiaru, jeśli przypiszesz indeksowi poza polem_", jest podstawową cechą Matlaba. Przechwytywanie tego zachowania wydaje się być trudne. –
Czy jesteś zainteresowany tylko zadaniami _jedno-wymiarowymi, _jedno-indeksowymi? To znaczy, czy twój kod może zawierać coś w rodzaju 'x = zera (a, 1) x (a + 1: a + 10) = 1;'? Lub 'x = zera (a, b) x (a + 1, b) = 1;'? –
Prawie chcę powiedzieć nie, aby to było możliwe tylko dlatego, że czuję, że niektóre z podstawowych narzędzi Matlaba polegają na tej funkcjonalności ... –