Odpowiedzi:
Różnica między czasem kompilacji a czasem wykonywania jest przykładem tego, co sprytni teoretycy nazywają rozróżnieniem fazowym . Jest to jedna z najtrudniejszych koncepcji do nauki, szczególnie dla osób bez dużego doświadczenia w językach programowania. Aby podejść do tego problemu, warto zapytać
To, co może pójść nie tak, to błędy w czasie wykonywania :
Mogą również występować błędy wykrywane przez sam program:
Myślę o tym pod kątem błędów i kiedy można je złapać.
Czas kompilacji:
string my_value = Console.ReadLine();
int i = my_value;
Do wartości ciągu nie można przypisać zmiennej typu int, więc kompilator na pewno wie w czasie kompilacji, że ten kod ma problem
Czas pracy:
string my_value = Console.ReadLine();
int i = int.Parse(my_value);
Tutaj wynik zależy od tego, jaki ciąg znaków został zwrócony przez ReadLine (). Niektóre wartości mogą być analizowane jako int, inne nie. Można to ustalić tylko w czasie wykonywania
.app
rozszerzenia? czy zdarza się to przy każdym uruchomieniu aplikacji przez użytkownika?
Czas kompilacji: okres, w którym Ty, programista, kompilujesz swój kod.
Czas działania: okres, w którym użytkownik uruchamia oprogramowanie.
Czy potrzebujesz bardziej przejrzystej definicji?
int x = 3/0
ale nic nie robisz z tą zmienną. Nie drukujemy tego ani nic. Czy nadal będzie to uważane za błąd wykonania?
( edytuj : poniższe informacje dotyczą języka C # i podobnych, mocno pisanych języków programowania. Nie jestem pewien, czy to ci pomoże).
Na przykład następujący kompilator zostanie wykryty przez kompilator (w czasie kompilacji ) przed uruchomieniem programu i spowoduje błąd kompilacji:
int i = "string"; --> error at compile-time
Z drugiej strony kompilator nie może wykryć następującego błędu: Otrzymasz błąd / wyjątek w czasie wykonywania (gdy program jest uruchomiony).
Hashtable ht = new Hashtable();
ht.Add("key", "string");
// the compiler does not know what is stored in the hashtable
// under the key "key"
int i = (int)ht["key"]; // --> exception at run-time
Tłumaczenie kodu źródłowego na działające na ekranie [dysk | dysk | sieć] może odbywać się (z grubsza) na dwa sposoby; nazwać ich kompilacją i tłumaczeniem.
W skompilowanym programie (przykładami są c i fortran):
Mówi się, że rzeczy, które zdarzają się w pierwszym kroku, mają miejsce w „czasie kompilacji”, a rzeczy, które zdarzają się w drugim kroku, mają miejsce w „czasie wykonywania”.
W interpretowanym programie (przykład MicroSoft basic (on dos) i python (myślę)):
W takim przypadku różnica między czasem kompilacji a czasem wykonywania jest trudniejsza do ustalenia i znacznie mniej istotna dla programisty lub użytkownika.
Java jest rodzajem hybrydy, w której kod jest kompilowany do kodu bajtowego, który następnie działa na maszynie wirtualnej, która zwykle jest interpreterem kodu bajtowego.
Istnieje również przypadek pośredni, w którym program jest kompilowany do kodu bajtowego i uruchamiany natychmiast (jak w awk lub perl).
Zasadniczo, jeśli Twój kompilator może zrozumieć, co masz na myśli lub jaką wartość ma „w czasie kompilacji”, może to zakodować na stałe w kodzie wykonawczym. Oczywiście, jeśli kod środowiska wykonawczego musi wykonywać obliczenia za każdym razem, gdy będzie działał wolniej, więc jeśli można coś ustalić w czasie kompilacji, jest znacznie lepiej.
Na przykład.
Stałe składanie:
Jeśli napiszę:
int i = 2;
i += MY_CONSTANT;
Kompilator może wykonać tę kalkulację w czasie kompilacji, ponieważ wie, co to jest 2 i czym jest MY_CONSTANT. W ten sposób oszczędza się wykonywania obliczeń przy każdym wykonaniu.
Rzeczy, które są wykonywane w czasie kompilacji, ponoszą (prawie) nie kosztują, gdy uruchamiany jest program wynikowy, ale mogą powodować duże koszty podczas kompilacji programu.
Mniej więcej dokładnie odwrotnie. Niewielkie koszty podczas kompilacji, większe koszty podczas uruchamiania programu.
Z innej strony; Jeśli coś jest wykonywane w czasie kompilacji, działa tylko na komputerze, a jeśli coś jest w czasie wykonywania, działa na komputerze użytkownika.
Przykładem tego, gdzie jest to ważne, jest typ nośny jednostki. Wersja czasu kompilacji (jak Boost.Units lub moja wersja w D ) kończy się tak samo szybko, jak rozwiązanie problemu z natywnym kodem zmiennoprzecinkowym, podczas gdy wersja wykonawcza kończy się pakowaniem informacji o jednostkach, które są wartościami i wykonuj w nich kontrole obok każdej operacji. Z drugiej strony wersje czasu kompilacji wymagają, aby jednostki wartości były znane w czasie kompilacji i nie mogły poradzić sobie z przypadkiem, gdy pochodzą one z danych wejściowych w czasie wykonywania.
Z poprzedniej podobnej odpowiedzi na pytanie Jaka jest różnica między błędem wykonania a błędem kompilatora?
Błędy kompilacji / Czas kompilacji / Składnia / Semantyczne: Błędy kompilacji lub czasu kompilacji są błędami, które wystąpiły w wyniku błędu literowego, jeśli nie będziemy przestrzegać właściwej składni i semantyki dowolnego języka programowania, wówczas kompilator generuje błędy czasu kompilacji. Nie pozwolą Twojemu programowi na wykonanie pojedynczego wiersza, dopóki nie usuniesz wszystkich błędów składniowych lub dopóki nie zdebugujesz błędów czasu kompilacji.
Przykład: brak średnika w C lub błędne wpisanie int
jako Int
.
Błędy w czasie wykonywania: Błędy w czasie wykonywania to błędy, które są generowane, gdy program działa. Tego rodzaju błędy powodują, że Twój program zachowuje się nieoczekiwanie, a nawet może go zabić. Są one często nazywane wyjątkami.
Przykład: Załóżmy, że czytasz plik, który nie istnieje, spowoduje błąd działania.
Przeczytaj więcej o wszystkich błędach programowania tutaj
Jako dodatek do innych odpowiedzi, oto jak wyjaśnię to laikowi:
Twój kod źródłowy jest jak plan statku. Określa sposób wykonania statku.
Jeśli oddasz swój plan stoczni, a podczas budowy statku znajdą usterkę, przestaną ją budować i zgłoś ją natychmiast, zanim statek opuści suchą przystań lub dotknie wody. Jest to błąd czasu kompilacji. Statek nigdy nawet nie unosił się na wodzie ani nie korzystał z silników. Błąd został znaleziony, ponieważ uniemożliwił nawet wykonanie statku.
Kiedy twój kod się kompiluje, to tak, jakby statek był ukończony. Zbudowany i gotowy do pracy. Wykonanie kodu to jak wypuszczenie statku w podróż. Pasażerowie są wsiadani, silniki pracują, a kadłub jest na wodzie, więc jest to czas pracy. Jeśli twój statek ma fatalną wadę, która tonie w jego dziewiczym rejsie (a może trochę później po dodatkowe bóle głowy), oznacza to, że wystąpił błąd w czasie wykonywania.
Na przykład: W silnie typowanym języku typ można sprawdzić w czasie kompilacji lub w czasie wykonywania. W czasie kompilacji oznacza to, że kompilator narzeka, jeśli typy nie są kompatybilne. W czasie wykonywania oznacza, że możesz dobrze skompilować swój program, ale w czasie wykonywania zgłasza wyjątek.
czas kompilacji: Deweloper zapisuje program w formacie .java i konwertuje do kodu bajtowego, który jest plikiem klasy, podczas tej kompilacji każdy błąd można zdefiniować jako błąd czasu kompilacji.
Czas działania: Wygenerowany plik .class jest wykorzystywany przez aplikację do dodatkowej funkcjonalności, a logika okazuje się nieprawidłowa i generuje błąd, który jest błędem w czasie wykonywania
Oto cytat Daniela Lianga, autora „Wstępu do programowania w JAVA” na temat kompilacji:
„Program napisany w języku wysokiego poziomu nazywany jest programem źródłowym lub kodem źródłowym. Ponieważ komputer nie może wykonać programu źródłowego, program źródłowy musi zostać przetłumaczony na kod maszynowy w celu wykonania . Tłumaczenie można wykonać za pomocą innego narzędzia programistycznego o nazwie tłumacz lub kompilator . ” (Daniel Liang, „Wprowadzenie do programowania JAVA” , s. 8).
...On kontynuuje...
„Kompilator tłumaczy cały kod źródłowy na plik kodu maszynowego , a następnie plik kodu maszynowego jest wykonywany”
Kiedy wciskamy kod wysokiego poziomu / czytelny dla człowieka, jest to na początku bezużyteczne! Musi to zostać przetłumaczone na sekwencję „elektronicznych wydarzeń” w twoim małym, małym procesorze! Pierwszym krokiem w tym kierunku jest kompilacja.
Mówiąc wprost: błąd kompilacji występuje podczas tej fazy, natomiast błąd wykonania pojawia się później.
Pamiętaj: sam fakt, że program jest skompilowany bezbłędnie, nie oznacza, że będzie działał bezbłędnie.
Błąd czasu wykonywania wystąpi w części gotowej, działającej lub oczekującej cyklu życia programów, natomiast błąd czasu kompilacji wystąpi przed „nowym” etapem cyklu życia.
Przykład błędu czasu kompilacji:
Błąd składni - jak można skompilować kod w instrukcji na poziomie komputera, jeśli są one niejednoznaczne? Twój kod musi być w 100% zgodny z regułami składniowymi języka, w przeciwnym razie nie będzie można go skompilować w działający kod maszynowy .
Przykład błędu w czasie wykonywania:
Brak pamięci - na przykład wywołanie funkcji rekurencyjnej może spowodować przepełnienie stosu, biorąc pod uwagę zmienną określonego stopnia! Jak to kompilator może przewidzieć !? nie może.
Na tym polega różnica między błędem kompilacji a błędem wykonania
Czas kompilacji:
Rzeczy, które są wykonywane w czasie kompilacji, ponoszą (prawie) nie kosztują, gdy uruchamiany jest program wynikowy, ale mogą powodować duże koszty podczas kompilacji programu. Czas pracy:
Mniej więcej dokładnie odwrotnie. Niewielkie koszty podczas kompilacji, większe koszty podczas uruchamiania programu.
Z innej strony; Jeśli coś jest wykonywane w czasie kompilacji, działa tylko na komputerze, a jeśli coś jest w czasie wykonywania, działa na komputerze użytkownika.
Czas kompilacji: czas kompilacji kodu źródłowego na kod maszynowy, tak aby stał się plikiem wykonywalnym, nazywa się czasem kompilacji.
Czas działania: gdy aplikacja jest uruchomiona, nazywa się to czasem działania.
Błędy czasu kompilacji to błędy składniowe, brakujące błędy odwołania do pliku. Błędy czasu wykonywania występują po skompilowaniu kodu źródłowego w programie wykonywalnym i podczas działania programu. Przykładami są awarie programów, nieoczekiwane zachowanie programu lub funkcje nie działają.
Wyobraź sobie, że jesteś szefem i masz asystenta i pokojówkę, i dajesz im listę zadań do wykonania, asystent (czas kompilacji) przejmie tę listę i sprawdzi, czy zadania są zrozumiałe i czy nie pisał w żadnym niezręcznym języku lub składni, więc rozumie, że chcesz przypisać kogoś do pracy, więc przypisuje go dla ciebie i rozumie, że chcesz kawy, więc jego rola się skończyła i pokojówka (czas pracy) zaczyna wykonywać te zadania, więc idzie zrobić ci kawę, ale nagle nie znajduje kawy, więc przestaje ją robić, albo zachowuje się inaczej i podaje ci herbatę (kiedy program działa inaczej, ponieważ znalazł błąd ).
Oto rozszerzenie odpowiedzi na pytanie „różnica między czasem wykonania a czasem kompilacji?” - Różnice w kosztach ogólnych związanych z czasem wykonywania i czasem kompilacji?
Wydajność produktu w czasie pracy przyczynia się do jego jakości poprzez szybsze dostarczanie wyników. Wydajność produktu w czasie kompilacji przyczynia się do jego aktualności poprzez skrócenie cyklu edycji-kompilacji-debugowania. Jednak zarówno wydajność w czasie wykonywania, jak i wydajność w czasie kompilacji są drugorzędnymi czynnikami w osiągnięciu terminowej jakości. Dlatego należy rozważyć poprawę wydajności w czasie wykonywania i kompilacji tylko wtedy, gdy jest to uzasadnione poprawą ogólnej jakości produktu i terminowości.
Świetne źródło do dalszego czytania tutaj :
Zawsze myślałem o tym w stosunku do ogólnych kosztów przetwarzania programu i o tym, jak wpływa to na wydajność, jak już wcześniej wspomniano. Prostym przykładem byłoby albo zdefiniowanie absolutnej pamięci wymaganej dla mojego obiektu w kodzie, albo nie.
Zdefiniowana wartość logiczna zajmuje pamięć x, która znajduje się w skompilowanym programie i nie można jej zmienić. Po uruchomieniu program wie dokładnie, ile pamięci należy przeznaczyć na x.
Z drugiej strony, jeśli po prostu zdefiniuję ogólny typ obiektu (tj. Rodzaj nieokreślonego uchwytu miejsca lub może wskaźnik do jakiegoś gigantycznego obiektu blob), rzeczywista pamięć wymagana dla mojego obiektu nie będzie znana, dopóki program nie zostanie uruchomiony i coś mu przypisam , dlatego należy to ocenić, a alokacja pamięci itp. zostanie następnie obsłużona dynamicznie w czasie wykonywania (więcej narzutu w czasie wykonywania).
To, jak jest obsługiwane dynamicznie, zależy od języka, kompilatora, systemu operacyjnego, kodu itp.
Od tej notatki będzie to jednak naprawdę zależeć od kontekstu, w którym używasz czasu wykonania vs czasu kompilacji.
możemy je zaklasyfikować do różnych dwóch szerokich grup wiązania statycznego i wiązania dynamicznego. Opiera się na tym, kiedy wiązanie jest wykonywane z odpowiednimi wartościami. Jeśli odwołania są rozstrzygane w czasie kompilacji, wówczas jest to wiązanie statyczne, a jeśli odniesienia są rozstrzygane w czasie wykonywania, to jest to wiązanie dynamiczne. Wiązanie statyczne i dynamiczne nazywane również wiązaniem wczesnym i późnym. Czasami są one również określane jako polimorfizm statyczny i polimorfizm dynamiczny.
Joseph Kulandai.
Główną różnicą między czasem wykonywania a czasem kompilacji jest:
int a = 1
int b = a/0;
tutaj pierwsza linia nie ma średnika na końcu ---> błąd czasu kompilacji po uruchomieniu programu podczas wykonywania operacji b, wynik jest nieskończony ---> błąd czasu wykonania.
oto bardzo prosta odpowiedź:
Czas działania i czas kompilacji to terminy programowania odnoszące się do różnych etapów tworzenia oprogramowania. Aby utworzyć program, programista najpierw pisze kod źródłowy, który określa sposób działania programu. Małe programy mogą zawierać tylko kilkaset linii kodu źródłowego, podczas gdy duże programy mogą zawierać setki tysięcy linii kodu źródłowego. Kod źródłowy musi zostać skompilowany w kod maszynowy, aby stać się programem wykonywalnym. Ten proces kompilacji nazywany jest czasem kompilacji (pomyśl o kompilatorze jako tłumaczu)
Skompilowany program może zostać otwarty i uruchomiony przez użytkownika. Gdy aplikacja jest uruchomiona, nazywa się to środowiskiem wykonawczym.
Terminy „środowisko wykonawcze” i „czas kompilacji” są często używane przez programistów w odniesieniu do różnych rodzajów błędów. Błąd czasu kompilacji to problem, taki jak błąd składni lub brak odniesienia do pliku, który uniemożliwia kompilację programu. Kompilator generuje błędy czasu kompilacji i zwykle wskazuje, który wiersz kodu źródłowego powoduje problem.
Jeśli kod źródłowy programu został już skompilowany do programu wykonywalnego, może nadal występować błędy występujące podczas działania programu. Przykłady obejmują funkcje, które nie działają, nieoczekiwane zachowanie programu lub awarie programu. Tego rodzaju problemy nazywane są błędami środowiska wykonawczego, ponieważ występują one w środowisku wykonawczym.
IMHO musisz przeczytać wiele linków i zasobów, aby zrozumieć różnicę między czasem wykonania a czasem kompilacji, ponieważ jest to bardzo złożony temat. Mam poniżej listę niektórych z tych zdjęć / linków, które polecam.
Oprócz tego, co powiedziano powyżej, chcę dodać, że czasami zdjęcie jest warte 1000 słów:
Czas kompilacji CLR_diag, a następnie runtime2
from Wiki
https://en.wikipedia.org/wiki/Run_time https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase)
Czas działania, czas działania lub środowisko wykonawcze mogą odnosić się do:
Przetwarzanie danych
Czas działania (faza cyklu życia programu) , okres, w którym program komputerowy jest wykonywany
Runtime Library , biblioteka programów zaprojektowana do implementacji funkcji wbudowanych w język programowania
Runtime system , oprogramowanie zaprojektowane do obsługi wykonywania programów komputerowych
Wykonanie oprogramowania, proces wykonywania instrukcji jedna po drugiej podczas fazy wykonywania
Lista kompilatorów https://en.wikipedia.org/wiki/List_of_compilers
;
3.2 różnica między tymi 3 rzeczami: kompilacja vs kompilacja vs środowisko wykonawcze
https://www.quora.com/What-is-the-difference-between-build-run-and-compile Fernando Padoan, programista, który jest nieco ciekawy projektowania języka Odpowiedzi 23 lutego Wracam w związku na inne odpowiedzi:
uruchamianie powoduje, że jakiś binarny plik wykonywalny (lub skrypt dla języków interpretowanych) zostanie… dobrze wykonany jako nowy proces na komputerze; kompilacja to proces analizowania programu napisanego w jakimś języku wysokiego poziomu (wyższym w porównaniu do kodu maszynowego), sprawdzania jego składni, semantyki, łączenia bibliotek, być może robienia optymalizacji, a następnie tworzenia binarnego programu wykonywalnego jako wyniku. Ten plik wykonywalny może mieć postać kodu maszynowego lub innego rodzaju kodu bajtowego - to znaczy instrukcji kierowanych na jakąś maszynę wirtualną; budowanie zwykle obejmuje sprawdzanie i dostarczanie zależności, inspekcję kodu, kompilację kodu w plik binarny, uruchamianie automatycznych testów i pakowanie powstałych plików binarnych i innych zasobów (obrazów, plików konfiguracyjnych, bibliotek itp.) w określony format pliku do wdrożenia. Pamiętaj, że większość procesów jest opcjonalna, a niektóre zależą od docelowej platformy, dla której budujesz. Przykładowo, pakowanie aplikacji Java dla Tomcat spowoduje wyświetlenie pliku .war. Zbudowanie pliku wykonywalnego Win32 z kodu C ++ może po prostu wyprowadzić program .exe lub też spakować go w instalatorze .msi.
Spójrz na ten przykład:
public class Test {
public static void main(String[] args) {
int[] x=new int[-5];//compile time no error
System.out.println(x.length);
}}
Powyższy kod został pomyślnie skompilowany, nie ma błędu składniowego, jest całkowicie poprawny. Ale w czasie wykonywania generuje błąd.
Exception in thread "main" java.lang.NegativeArraySizeException
at Test.main(Test.java:5)
Podobnie jak w czasie kompilacji niektóre przypadki zostały sprawdzone, po tym czasie niektóre przypadki zostały sprawdzone, gdy program spełni wszystkie warunki, otrzymasz wynik. W przeciwnym razie pojawi się błąd kompilacji lub błąd wykonania.
klasa publiczna RuntimeVsCompileTime {
public static void main(String[] args) {
//test(new D()); COMPILETIME ERROR
/**
* Compiler knows that B is not an instance of A
*/
test(new B());
}
/**
* compiler has no hint whether the actual type is A, B or C
* C c = (C)a; will be checked during runtime
* @param a
*/
public static void test(A a) {
C c = (C)a;//RUNTIME ERROR
}
}
class A{
}
class B extends A{
}
class C extends A{
}
class D{
}
To nie jest dobre pytanie dla SO (nie jest to konkretne pytanie programistyczne), ale ogólnie nie jest złe.
Jeśli uważasz, że jest to trywialne: co z czasem odczytu a czasem kompilacji i kiedy jest to użyteczne rozróżnienie? Co z językami, w których kompilator jest dostępny w czasie wykonywania? Guy Steele (bez manekina, napisał) napisał 7 stron w CLTL2 o EVAL-WHEN, których programiści CL mogą użyć do kontrolowania tego. Dwa zdania ledwo wystarczą na definicję , która sama w sobie jest daleka od wyjaśnienia .
Ogólnie rzecz biorąc, jest to trudny problem, którego projektanci języków starali się uniknąć. Często mówią po prostu: „tutaj jest kompilator, robi rzeczy w czasie kompilacji; wszystko po tym jest w czasie wykonywania, baw się dobrze”. C ma być prosty do wdrożenia, a nie najbardziej elastyczne środowisko do obliczeń. Jeśli nie masz kompilatora dostępnego w czasie wykonywania lub nie masz możliwości łatwego kontrolowania oceny wyrażenia, zwykle dochodzi do włamań w języku w celu sfałszowania typowych zastosowań makr lub użytkownicy opracowują Wzory projektowe do symulacji mając mocniejsze konstrukty. Prosty w implementacji język może zdecydowanie być wartościowym celem, ale to nie znaczy, że jest to projekt projektowania języka programowania. (Nie używam EVAL-WHEN, ale nie wyobrażam sobie życia bez niego.)
A obszar problemów wokół czasu kompilacji i wykonywania jest ogromny i wciąż w dużej mierze niezbadany. Nie oznacza to, że SO jest właściwym miejscem do dyskusji, ale zachęcam ludzi do dalszej eksploracji tego terytorium, szczególnie tych, którzy nie mają z góry pojęcia, co to powinno być. Pytanie nie jest ani proste, ani głupie, a my moglibyśmy przynajmniej skierować inkwizytora we właściwym kierunku.
Niestety nie znam żadnych dobrych referencji na ten temat. CLTL2 mówi o tym trochę, ale nie nadaje się do nauki.