Na Stack Overflow jest kilku bardzo doświadczonych ludzi, którzy zawsze mówią o standardzie C. Ludzie wydają się nie lubić nieprzenośnych rozwiązań, nawet jeśli dla mnie działają. Ok, rozumiem, że należy przestrzegać tego standardu, ale czy nie ogranicza to kreatywności programisty?
Jakie są konkretne korzyści płynące z przestrzegania normy? Zwłaszcza, że kompilatory mogą nieco inaczej implementować standard.
programming-languages
c
standards
0decimal0
źródło
źródło
Odpowiedzi:
Istnieje kilka powodów, dla których trzymanie się standardu jest dobrą rzeczą.
Zamknięcie w kompilatorze jest do bani. Jesteś całkowicie na łasce grupy programistów z ich własnym programem. Najwyraźniej nie chcą cię zdobyć ani nic, ale jeśli twój kompilator zacznie opóźniać się w optymalizacji, nowych funkcjach, poprawkach bezpieczeństwa itp., To źle; Utknąłeś. W skrajnych przypadkach niektóre firmy muszą rozpocząć łatanie dowolnego narzędzia, od którego się uzależniły. Jest to ogromna strata pieniędzy i czasu, gdy istnieją inne narzędzia robocze.
Zamknięcie na platformie jest do bani mocniejsze. Jeśli naciskasz oprogramowanie na Linuksa i chcesz przejść na system Windows, ponieważ zdajesz sobie sprawę, że Twój rynek naprawdę istnieje, będziesz miał sporo czasu, zmieniając każdy nieprzenośny hack, który masz w kodzie, aby grać fajnie zarówno z GCC, jak i MSVC. Jeśli masz kilka podstawowych elementów opartych na czymś takim, powodzenia!
Najtrudniejsze są do tyłu niezgodne zmiany. Standard nigdy nie złamie twojego kodu (Ignoruj python). Jednak niektórzy pisarze kompilatorów losowych mogą zdecydować, że ten dodatek specyficzny dla implementacji nie jest wart zachodu i porzucić go. Jeśli zdarzy ci się na nim polegać, utkniesz na jakiejkolwiek starej, nieaktualnej wersji, w której był ostatnio.
Tak więc nadrzędny komunikat, trzymanie się standardu, czyni cię bardziej elastycznym . Masz bardziej ograniczony język, ale masz więcej
To delikatna równowaga, ale całkowite ignorowanie standardu jest zdecydowanie błędem. Mam tendencję do organizowania mojego kodu C, aby polegać na abstrakcjach, które mogą być zaimplementowane w sposób nieprzenośny, ale które mogę transparentnie przenosić bez zmiany wszystkiego, co zależy od abstrakcji.
źródło
Standard jest rodzajem „kontraktu” między tobą a twoim kompilatorem, który określa znaczenie twoich programów. Jako programiści często mamy pewien mentalny model działania języka, a ten model mentalny często jest niezgodny ze standardem. (Na przykład programiści C często myślą o wskaźniku jako z grubsza „liczbie całkowitej oznaczającej adres pamięci” i dlatego zakładają, że można bezpiecznie wykonywać dowolne operacje arytmetyczne / konwersje / manipulacje na wskaźnikach, które można wykonać za pomocą liczb całkowitych oznaczających pamięć adres. To założenie nie zgadza się ze standardem; w rzeczywistości nakłada bardzo surowe ograniczenia na to, co można zrobić ze wskaźnikami).
Jaka jest zatem korzyść z przestrzegania standardu, a nie własnego modelu mentalnego?
Mówiąc najprościej, chodzi o to, że standard jest poprawny, a twój własny model mentalny jest błędny. Twój model mentalny jest zwykle uproszczonym widokiem tego, jak rzeczy działają w twoim systemie, w typowych przypadkach, z wyłączonymi wszystkimi optymalizacjami kompilatora; dostawcy kompilatorów zazwyczaj nie starają się go dostosować, szczególnie jeśli chodzi o optymalizacje. (Jeśli nie wytrzymasz końca kontraktu, nie możesz oczekiwać od kompilatora żadnego konkretnego zachowania: wyrzucanie śmieci, wyrzucanie śmieci).
Lepiej byłoby powiedzieć „nawet jeśli wydają się dla mnie pracować”. O ile twój kompilator nie udokumentuje, że dane zachowanie będzie działać (to znaczy: chyba że używasz wzbogaconego standardu, składającego się ze standardowej właściwej dokumentacji kompilatora plus), nie wiesz, że to naprawdę działa lub że jest naprawdę niezawodne. Na przykład, przepełnienie liczb całkowitych ze znakiem zwykle powoduje zawijanie na wielu systemach (tak
INT_MAX+1
jest zazwyczajINT_MIN
) - z tym wyjątkiem, że kompilatory „wiedzą”, że podpisana arytmetyka liczb całkowitych nigdy nie przepełnia się w (poprawnym) programie C, i często wykonują bardzo zaskakujące optymalizacje na podstawie tego „ wiedza, umiejętności".źródło
-fwrapv
, a wtedy używasz nieco innego, niestandardowego języka, w którym arytmetyka liczb całkowitych zawsze się otacza.Nie. Standard mówi, co wolno robić. Jeśli nie jest określony, jesteś na terytorium nieokreślonego zachowania, a następnie wszystkie zakłady są wyłączone - program może nic zrobić.
Ponieważ wspomniałeś o konkretnym przykładzie
void main()
vsint main()
, mogę poprawić moją odpowiedź.void main()
nie jest standardową deklaracją głównej funkcji. Może działać na niektórych kompilatorach poprzez rozszerzenia, ale polega na implementacji. Nawet jeśli to działa, musisz sprawdzić, czy robi to, co chcesz. Problem polega na tym, że programiści kompilatorów mogą zdecydować o usunięciuvoid main()
w następnej wersji kompilatora, powodując uszkodzenie aplikacji.Z drugiej strony standard wyraźnie określa podpis main as
int main()
i mówi, co powinien zrobić.Z drugiej strony są rzeczy nie zdefiniowane w standardzie. Następnie może obowiązywać inny standard (na przykład POSIX). Najlepszym przykładem może być implementacja wątków w c ++ 03, ponieważ standardowe programy c ++ 03 były 1-wątkowe. W takim przypadku musisz użyć biblioteki zależnej od platformy lub czegoś w rodzaju ulepszenia .
źródło
Nie postępuj zgodnie z zasadami JEŻELI twój projekt dotyczy projektów specjalnych, na przykład projektu rządowego lub wojskowego, ale musisz przestrzegać zasad JEŻELI mówisz o otwartym źródle lub dużym projekcie z rozproszonym zespołem.
źródło