Standard języka C mówi że NULL ma się dać porównać do 0 (zera) nie definiuje jednak że ma być zerem! To oznacza że zawsze go należy porównywać do zera a nie zakładać że jest reprezentowany przez zero (bo może nie być). Niestety NULL także poddaje się niejawnym konwersjom do int i bywa definiowany przez... makro :-/ Nie posiada także definiowanego własnego typu co uniemożliwia wywołania polimorficzne.
Język tak w C (po C99) jak i w C++ (oj nie będę strzelał po której rewizji standardu...), zapewnione jest poprawne wykonanie zwolnionej pamięci wskazywanej przez NULL lub nullptr. free (dla C) lub delete (dla C++) nie robi wtedy.... nic :-)
Stąd przechodząc do sedna. Nie wywołuj funkcji z NULL a staraj się używać dostępnego po 2011 w C++ nullptr wraz z typem nullptr_t.
Tu masz przykład programu testowego działającego w g++ i clang++. Kompilatory MS także mają jakiś odpowiednik __PRETTY_FUNCTION__ ale go nie znam:
#include <iostream>
void fun1(int *, int *) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void fun2(int *, int *) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void fun2(std::nullptr_t, std::nullptr_t) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void fun3(int, int) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main() {
int a = 42;
int b = 43;
fun1(NULL, NULL);
fun2(&a, &b);
fun2(nullptr, nullptr);
fun3(NULL, NULL); // Tu w szanującym się kompilatorze pojawi się warning..
}
Wynik działania dla clang++:
void fun1(int *, int *)
void fun2(int *, int *)
void fun2(std::nullptr_t, std::nullptr_t)
void fun3(int, int)
Zwróć uwagę że fun2(...) jest wybierane polimorficznie a fun3(...) jest "małym skandalem konwersji" :-)