Pewna pośrednia potrzeba jest w przypadku złożonych programów (np. Struktury danych rekurencyjnych lub zmiennych wielkości). Jednak nie jest konieczne wdrażanie tej pośredniczości za pomocą wskaźników.
Większość języków programowania wysokiego poziomu (tj. Nie asemblerowych) jest dość bezpieczna dla pamięci i uniemożliwia nieograniczony dostęp do wskaźnika. Rodzina C jest tutaj dziwna.
C ewoluowało z B, co było bardzo cienką abstrakcją w stosunku do surowego zestawu. B miał jeden typ: słowo. Słowo może być użyte jako liczba całkowita lub jako wskaźnik. Te dwa są równoważne, gdy cała pamięć jest postrzegana jako pojedyncza ciągła tablica. C zachował to dość elastyczne podejście i nadal wspierał z natury niebezpieczną arytmetykę wskaźników. Cały system typu C jest bardziej przemyślany. Ta elastyczność dostępu do pamięci sprawiła, że C jest bardzo odpowiedni do jego podstawowego celu: prototypowania systemu operacyjnego Unix. Oczywiście Unix i C okazały się dość popularne, dlatego C jest również stosowany w aplikacjach, w których takie podejście do pamięci na niskim poziomie nie jest tak naprawdę potrzebne.
Jeśli spojrzymy na języki programowania występujące przed C (np. Dialekty Fortran, Algol, w tym Pascal, Cobol, Lisp,…), niektóre z nich obsługują wskaźniki podobne do C. Warto zauważyć, że koncepcja zerowego wskaźnika została wynaleziona dla Algola W w 1965 roku. Jednak żaden z tych języków nie próbował być językiem C, wydajnym językiem systemów o niskiej abstrakcji: Fortran był przeznaczony do obliczeń naukowych, Algol opracował kilka dość zaawansowanych koncepcji, Lisp był bardziej projekt badawczy niż język klasy przemysłowej, a Cobol koncentrował się na aplikacjach biznesowych.
Wywóz śmieci istniał od późnych lat 50., tj. Na długo przed C (wczesne lata 70.) GC wymaga bezpieczeństwa pamięci do prawidłowego działania. Języki przed i po C używały GC jako normalnej funkcji. Oczywiście sprawia to, że język jest znacznie bardziej skomplikowany i być może wolniejszy, co było szczególnie zauważalne w czasach komputerów mainframe. Języki GC były zorientowane na badania (np. Lisp, Simula, ML) i / lub wymagały wydajnych stacji roboczych (np. Smalltalk).
Dzięki mniejszym, bardziej wydajnym komputerom ogólnie, a języki GC stały się bardziej popularne. W przypadku aplikacji nie działających w czasie rzeczywistym (a czasem nawet wtedy) GC jest teraz preferowanym podejściem. Ale algorytmy GC były również przedmiotem intensywnych badań. Alternatywnie, poprawiono także bezpieczeństwo pamięci bez GC, szczególnie w ostatnich trzech dekadach: istotnymi innowacjami są RAII i inteligentne wskaźniki w C ++ oraz system sprawdzania / pożyczania Rust przez cały okres eksploatacji.
Java nie wprowadziła innowacji, ponieważ jest bezpiecznym językiem programowania: w zasadzie wzięła semantykę języka GCed, bezpiecznego języka Smalltalk i połączyła je ze składnią i statycznym typowaniem C ++. Następnie został wprowadzony na rynek jako lepszy, prostszy C / C ++. Ale to tylko powierzchownie potomek C ++. Brak wskaźników w Javie zawdzięcza znacznie bardziej obiektowemu modelowi Smalltalk niż odrzuceniu modelu danych C ++.
Tak więc „nowoczesnych” języków, takich jak Java, Ruby i C #, nie należy interpretować jako przezwyciężających problemy surowych wskaźników, takich jak w C, ale należy je postrzegać jako czerpiące z wielu tradycji - w tym C, ale także z bezpieczniejszych języków, takich jak Smalltalk, Simula, lub Lisp.