Czy void jest typem

2008-08-05 17:21

Jak wiadomo, w C i C++ nie ma procedur. Są tylko funkcje, czyli podprogramy obliczające i zwracające jakąś wartość. Jednak możliwe jest zadeklarowanie takiej funkcji, która w istocie nic nie zwraca; służy do tego słowo kluczowe void, rzecz jasna. Pełni ono wówczas rolę nazwy typu zwracanego przez funkcję:

  1. void Procedure { /* ... */ }

Ktoś mniej doświadczony (lub o mniej schematycznym podejściu do C++) mógłby wobec tego spytać: Czy void jest wobec tego rzeczywiście typem, takim jak chociażby int czy char, czy jednak jest to tylko dziwne słowo na oznaczenie procedur w C++?

Odpowiedzią na powyższe pytanie może być tylko stanowcze… i tak, i nie :)
Z jednej strony wiemy na przykład, że void może występować w nagłówkach funkcji, i to nie tylko w miejscu typu wartości zwracanej, ale też na liście parametrów. Jednakże w tym drugim przypadku oznacza to jedynie to, iż funkcja tak naprawdę nie przyjmuje żadnych argumentów. W C++ można spokojnie pominąć to użycie void, osiągając dokładnie ten sam efekt – funkcji bezparametrowej. (Warto aczkolwiek zaznaczyć, że w C jest inaczej).
Inną rolą void sugerującą jego “typowość” jest istnienie wskaźników typu void*. Do tego typu można niejawnie skonwertować dowolny wskaźnik:

  1. void* p = new CFoo;

Operacja odwrotna nie jest jednak możliwa (wymaga co najmniej static_cast), a sam void* nie jest tak naprawdę pełnoprawnym wskaźnikiem – nie pozwala bowiem na dereferencję. Ponadto nie istnieje też typ referencyjny void&.
Wreszcie, chyba najbardziej egzotycznym użyciem void jest rzutowanie na niego wyrażenia innego typu. Jest to jak najbardziej możliwe i dotyczy zwykle sytuacji podobnych do tej:

  1. // Pokaż okno komunikatu tylko z przyciskiem OK
  2. static_cast<void>(MessageBox(NULL, _TEXT("Błąd!"), NULL, MB_OK | MB_ICONERROR));

Używamy tutaj funkcji, która zwraca rezultat (int), ale on nas nie interesuje. Pokazujemy przecież komunikat z jednym przyciskiem OK (więc nie musimy pobierać decyzji użytkownika), a ponadto nie ma tutaj żadnej wyobrażalnej możliwości wystąpienia błędu, o którym mógłby nas poinformować rezultat funkcji. Niektóre kompilatory z włączonym maksymalnym poziomem ostrzeżeń mogą aczkolwiek ostrzegać o ignorowaniu potencjalnie przydatnego rezultatu funkcji; rzutowanie na void pozwala takich ostrzeżeń uniknąć. Jednak sam fakt, iż takie rzutowanie jest możliwe, nie implikuje od razu możliwości zadeklarowania zmiennej typu void. To w jest rzecz jasna niemożliwe.

Cóż więc z tym fantem zrobić? No cóż, sprawa jest raczej śliska. Zapewne dałoby się jeszcze znaleźć przynajmniej po kilka argumentów zarówno za tym, że void typem jest, jak i że nie jest. Ale od rozstrzygnięcia ważniejsze jest raczej to, aby z tego… słowa kluczowego (pozostańsmy przy neutralnej wersji) umieć korzystać. Co, swoją drogą, nie jest takie trudne ;)

Tags: ,
Author: Xion, posted under Programming »



Adding comments is disabled.

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.