sdm@cs.brown.edu (Scott Meyers) (05/06/91)
What is the type of the constant "0", independent of any context? If there is such a default type, call it T. Then are there any conversions in any of the following? int i = 0; // conversion from T to int? int *ip = 0; // conversion from T to int*? double d = 0; // conversion from T to double? The reason for asking is that it would be nice to avoid the following ambiguity: void f(int x); // parameter of a numerical type void f(char *s); // parameter of a pointer type f(0); // ambiguous call -- is 0 an int or a char*? I would prefer that the default type for 0 be int, in accord with the default type of functions and consts. Then the call to f(0) would resolve to calling f(int) and there would be no ambiguity. It would of course still be possible to call f(char*) via an explicit cast or, more palatibly, by declaring a const null pointer of the appropriate type, e.g., const char *NULLSTRING = 0; f(NULLSTRING); Unfortunately, we'd have to augment the rules for disambiguating overloaded functions described in section 13.2 of the ARM (pp. 312ff of the American edition). There are currently five rules. I'd add the conversion of "0" to "null pointer" to rule 3, on standard conversions. I suspect the matter is substantially more complicated and subtle than I've described here. Comments? Scott ------------------------------------------------------------------------------- What do you say to a convicted felon in Providence? "Hello, Mr. Mayor."
steve@taumet.com (Stephen Clamage) (05/07/91)
sdm@cs.brown.edu (Scott Meyers) writes: >What is the type of the constant "0", independent of any context? A literal zero has type int. It can also serve as a null pointer constant when initializing a pointer. int i = 0; // 0 has type int double d = 0; // 0 implicitly converted to type double T* t = 0; // 0 implicitly converted to type T* T* u = i; // illegal, since i is not a null pointer constant >The reason for asking is that it would be nice to avoid the following >ambiguity: > void f(int x); // parameter of a numerical type > void f(char *s); // parameter of a pointer type > f(0); // ambiguous call -- is 0 an int or a char*? This is not ambiguous. The zero is an exact match to f(int), but requires a conversion to f(char*). If your compiler calls it ambiguous, this is a bug. -- Steve Clamage, TauMetric Corp, steve@taumet.com
juul@diku.dk (Anders Juul Munch) (05/07/91)
sdm@cs.brown.edu (Scott Meyers) writes: >What is the type of the constant "0", independent of any context? If there >is such a default type, call it T. Then are there any conversions in any >of the following? > int i = 0; // conversion from T to int? > int *ip = 0; // conversion from T to int*? > double d = 0; // conversion from T to double? >The reason for asking is that it would be nice to avoid the following >ambiguity: > void f(int x); // parameter of a numerical type > void f(char *s); // parameter of a pointer type > f(0); // ambiguous call -- is 0 an int or a char*? [stuff deleted] Try: printf("%d,%d,%d\n", sizeof(int), sizeof(void*), sizeof(0)); on a system with different sizes for int and pointers. What you'll find is that "0" is foremost an integer (which incidentally may be used in place of a pointer :-). But I wonder, if we have #define NULL 0 (which is ANSI C compliant, I don't know if C++ is any different), then f(NULL) would call f(int)?! This seems highly unreasonable to me, and it looks like yet another good reason why the implicit conversion of 0 to the null pointer should be disallowed. Instead, NULL should be used whenever a null pointer is needed. NULL being defined as #define NULL ((void*)0) And int* ip = 0; would then be illegal, and replaced by int* ip = NULL; -- Anders Munch
chip@tct.com (Chip Salzenberg) (05/10/91)
According to juul@diku.dk (Anders Juul Munch): >But I wonder, if we have > #define NULL 0 >(which is ANSI C compliant, I don't know if C++ is any different), then >f(NULL) would call f(int)?! This seems highly unreasonable to me ... That's the fact, Jack. When in doubt, cast. >looks like yet another good reason why the implicit conversion of 0 to the >null pointer should be disallowed. Too late for that; implicit conversion of 0 to a pointer isn't even a C++ invention. As an ANSI C feature, I doubt it will disappear. >Instead, NULL should be used whenever a null pointer is needed. NULL being >defined as > #define NULL ((void*)0) >And > int* ip = 0; >would then be illegal, and replaced by > int* ip = NULL; Sorry, that won't work. The ARM explicitly disallows automatic (castless) conversion of a |void*| to another pointer type. -- Brand X Industries Sentient and Semi-Sentient Being Resources Department: Because Sometimes, "Human" Just Isn't Good Enough [tm] Chip Salzenberg <chip@tct.com>, <uunet!pdn!tct!chip>
horstman@mathcs.sjsu.edu (Cay Horstmann) (05/10/91)
In article <1991May7.162035.9247@odin.diku.dk> juul@diku.dk (Anders Juul Munch) writes: > >But I wonder, if we have > #define NULL 0 >(which is ANSI C compliant, I don't know if C++ is any different), then >f(NULL) would call f(int)?! This seems highly unreasonable to me, and it >looks like yet another good reason why the implicit conversion of 0 to the >null pointer should be disallowed. >Instead, NULL should be used whenever a null pointer is needed. NULL being >defined as > #define NULL ((void*)0) >And > int* ip = 0; >would then be illegal, and replaced by > int* ip = NULL; > Beware of DOS header files that define NULL as 0L in the large memory model!!! 0L is NOT convertible into a pointer. I got bitten by that one when switching from Glockenspiel to Borland C++ Cay
tmb@ai.mit.edu (Thomas M. Breuel) (05/10/91)
In article <282980FB.6AB7@tct.com> chip@tct.com (Chip Salzenberg) writes: According to juul@diku.dk (Anders Juul Munch): >But I wonder, if we have > #define NULL 0 >(which is ANSI C compliant, I don't know if C++ is any different), then >f(NULL) would call f(int)?! This seems highly unreasonable to me ... That's the fact, Jack. When in doubt, cast. >looks like yet another good reason why the implicit conversion of 0 to the >null pointer should be disallowed. Too late for that; implicit conversion of 0 to a pointer isn't even a C++ invention. As an ANSI C feature, I doubt it will disappear. A possible fix to this mess might be to introduce a new value "nil" that behaves mostly like "0", but is not an integer.
jerbil@ultra.com (Joseph Beckenbach {Adapter Software Release Engr}) (05/10/91)
In his article Thomas M. Breuel <tmb@ai.mit.edu> writes concerning implicit conversion of 0 to types, or lack of such conversion. >A possible fix to this mess might be to introduce a new value "nil" >that behaves mostly like "0", but is not an integer. I've stopped using 0 (as pointer) and NULL directly in my C code, and have finessed the problem with #define NIL(type) ((type)NULL) For me it's the easiest solution, since I tend not to think of a generic 'nil' pointer but of a 'nil pointer of type T'. What other reasonable schemes can be used for the same effect? Joseph Beckenbach -- Joseph Beckenbach jerbil@ultra.com VEGGIES FOREVER! work 408-922-0100 x246
chip@tct.com (Chip Salzenberg) (05/14/91)
According to tmb@ai.mit.edu (Thomas M. Breuel): >A possible fix to this mess might be to introduce a new value "nil" >that behaves mostly like "0", but is not an integer. I like it. It's too late to save ANSI C, but C++ could finally provide the vehicle to end the NULL wars. -- Brand X Industries Custodial, Refurbishing and Containment Service: When You Never, Ever Want To See It Again [tm] Chip Salzenberg <chip@tct.com>, <uunet!pdn!tct!chip>