2012-04-29 20 views
8

W C++ możesz używać zarówno ogólnych, jak i typu bezpiecznych pojemników za pomocą szablonów. Jednak w C, jeśli chcesz generycznych pojemników, musisz (afaik) użyć void*, co oznacza, że ​​tracisz bezpieczeństwo typu. Aby mieć bezpieczne kontenery typu, trzeba je ponownie wdrożyć dla każdego rodzaju danych, które chcesz przechowywać.W C, Ogólne pojemniki lub bezpieczne pojemniki?

Biorąc pod uwagę, że C następuje bardziej the-programista-wie-co-On jest czynieniu filozofię niż C++, co byłoby bardziej idiomatyczne rzeczą do zrobienia w C: używać pojemników rodzajowe z void*, lub dokonać własnych pojemników na każdy typ danych?

Odpowiedz

3

będę dążyć do pojemników generycznych:

  1. Po przyzwyczaić się do tego, po prostu myśleć void * jest sens typ coś kiedy nie dbam o to typ. To jest jak Object w Javie - gdzie przez długi czas pojemniki generyczne również nie miały bezpieczeństwa typu.

  2. Masz tylko jedno miejsce na ulepszenia.

  3. Nie otrzymujesz bezpieczeństwa typu; ale przy wielokrotnym wdrażaniu bezpiecznych pojemników typu ryzykujesz błędy kopiowania i wklejania. To też może prowadzić do błędów.

0

Aby utworzyć typ, który obsługuje dane ogólne w C, należy użyć wartości void* do przekazania danych. Niepraktyczne jest definiowanie nowych algorytmów dla każdego możliwego typu.

+0

Można zdefiniować tylko te algorytmy, które są potrzebne. Ale widzę, co mówisz. –

+0

@PaulManta: Tak, schodziłem z przykładu kontenera, który powinien obsługiwać dowolne typy. –

0

masz żadnej realnej korzyści stosując void* jako członek (o ile, powiedzmy, czasy kompilacji są najważniejsze), zawsze można rzucić do void* gdzie stosowne, następnie działać na niewstukane bąble danych, gdzie jest to konieczne.

Zaimplementowałem takie interfejsy w C (na przykład wiele wariantów o nazwanych polach różnych typów). Opowiadałem się za bezpieczeństwem typu i rzadko znajdowałem rzucanie do void* dobrze w tych implementacjach.

... potem znowu, i spędzają więcej czasu niż pisanie C++ c :)

0

Więc musiałem szybkiego wyszukiwania, aby sprawdzić, czy jakieś nowe pomysłowe wyszedł w dziedzinie kontenerów C.

Znalazłem this. Jest to całkiem dokładna próba kompletnej biblioteki kontenerów C.

Przekazuje elementy, które mają być zawarte w wskaźnikach void *. Nie ma próby określenia struktur określonego typu.

Dla bezpieczeństwa typu można napisać makro "opakowanie" dla każdego kontenera, które definiuje hosta, jeśli funkcje inline otaczają wersję bez typu i zapewniają bezpieczeństwo typu. Mam nadzieję, że zostaną zoptymalizowane przez kompilator, ale nie zawsze jest to możliwe. A makra będą brzydkie.

Sądzę, że jest to jeden z powodów, dla których więcej programów (aplikacji) jest napisanych w języku C++ zamiast C. Możliwość tworzenia złożonych abstrakcji w języku C jest ograniczona. Możesz to zrobić, ale zazwyczaj poświęcasz inne aspekty, takie jak wydajność lub łatwość konserwacji (sprawdź na przykład program C GTK).

+0

Dzięki nowemu słowu kluczowemu '_Generic' języka C11 te makra nie mogą być zbyt brzydkie. Clang już to zaimplementował, a gcc ma również wystarczającą liczbę funkcji do emulowania go. –