2 ms·
This has nothing to do with the preprocessor. The concept of NULL existed before the macro was standardized. Literal zeros were the way to refer to it which was
by kevin_thibedeau 3y ago
This has nothing to do with the preprocessor. The concept of NULL existed before the macro was standardized. Literal zeros were the way to refer to it which was a design mistake.
- kazinator 3y agoI think it's a fine design. Obviously, the C++ people who invented virtual void fun() = 0; were blind to whatever mistake it embodies. When I gained the proper understanding that 0 is a null pointer constant, I immediatelly stopped using NULL. It's so much nicer. - It works fine in a typeless language in which every value is a machine word, and integers and the null pointer share exactly the same representation. - It works fine in a strongly typed language, where context indicates what zero means, even in the context of different types of different sizes and representations. Unfortunately C (and also C++) contains some untyped areas, like variadic argument lists. I would have designed it differently: only the token 0 would have the special overloaded meaning, and not all constant zero-valued expressions of any integer type. So (0 + 0) would not be a null pointer. In unsafe contexts, the use of a 0 token would be diagnosed. printf("...", ... 0, ...); // diagnosed printf("...", ... 0L, ...); // not diagnosed: argument of long type printf("...", ... 0 + 0, ...); // not diagnosed: argument of int type printf("...", ... (void *) 0, ...); // not diagnosed: null pointer of (void *) type. I think I would also not have the hexadecimal or octal zero tokens be the null pointer constant: char *p = 0; // null pointer, no diagnostic char *q = 0x0; // error, integer to pointer with no cast The downside is that the AST would have to retain that representation detail somewhere (possibly just in a single Boolean flag).
- kevin_thibedeau 3y agoThis isn't just a C++-ism. The null pointer constants are only more prominent in C++ because of the rejection of void * even though it isn't any "safer" to have a special integer literal with the same semantics. Ultimately, it all comes from K&R C. There are legitimate cases where you need a function pointer assigned to address zero (reset vectors commonly). The correct behavior in C is ambiguous if the null address isn't also 0 since the standard doesn't call out special behavior for function pointers. That wouldn't be the case if nullptr had been standardized earlier and there was no need for the magic 0 as a null pointer constant.