* Re: linux libio status [not found] <199710150623.XAA06491.cygnus.egcs@atrus.synopsys.com> @ 1997-10-15 2:10 ` Jason Merrill 1997-10-15 9:15 ` Joe Buck 0 siblings, 1 reply; 34+ messages in thread From: Jason Merrill @ 1997-10-15 2:10 UTC (permalink / raw) To: Joe Buck, egcs >>>>> Joe Buck <jbuck@synopsys.com> writes: > We need to silence these warnings. For the NULL, I suggest a global > s/NULL/0/ in the C++ iostreams headers. There is no reason to write > NULL, it is just a source of problems like this (*especially* since > we have changed C++ to be strict about void*). But that won't help user code that uses NULL. Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 2:10 ` linux libio status Jason Merrill @ 1997-10-15 9:15 ` Joe Buck 1997-10-15 11:12 ` Per Bothner 1997-10-15 14:33 ` linux libio status Richard Henderson 0 siblings, 2 replies; 34+ messages in thread From: Joe Buck @ 1997-10-15 9:15 UTC (permalink / raw) To: Jason Merrill; +Cc: jbuck, egcs > >>>>> Joe Buck <jbuck@synopsys.com> writes: > > > We need to silence these warnings. For the NULL, I suggest a global > > s/NULL/0/ in the C++ iostreams headers. There is no reason to write > > NULL, it is just a source of problems like this (*especially* since > > we have changed C++ to be strict about void*). > > But that won't help user code that uses NULL. The comp.lang.c++ tells users "don't use NULL in C++ programming", precisely for this reason. The only other alternatives I can think of is to force a #define NULL 0, or do some kind of mini-fixincludes on the existing libio.h header. (The latter technique could solve the problems with the new lock functions as well). ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 9:15 ` Joe Buck @ 1997-10-15 11:12 ` Per Bothner 1997-10-15 14:33 ` Joe Buck 1997-10-15 16:51 ` Peter Seebach 1997-10-15 14:33 ` linux libio status Richard Henderson 1 sibling, 2 replies; 34+ messages in thread From: Per Bothner @ 1997-10-15 11:12 UTC (permalink / raw) To: egcs Joe Buck <jbuck@synopsys.com> writes: > The comp.lang.c++ tells users "don't use NULL in C++ programming", > precisely for this reason. I am strongly opposed to any such advice, or to anything that makes that advice necessary. Using NULL instead of 0 makes programs clearer, and is strongly to be encouraged. --Per Bothner Cygnus Solutions bothner@cygnus.com http://www.cygnus.com/~bothner ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 11:12 ` Per Bothner @ 1997-10-15 14:33 ` Joe Buck 1997-10-15 16:51 ` Per Bothner [not found] ` <199710152351.QAA02138.cygnus.egcs@cygnus.com> 1997-10-15 16:51 ` Peter Seebach 1 sibling, 2 replies; 34+ messages in thread From: Joe Buck @ 1997-10-15 14:33 UTC (permalink / raw) To: Per Bothner; +Cc: egcs > Joe Buck <jbuck@synopsys.com> writes: > > The comp.lang.c++ tells users "don't use NULL in C++ programming", > > precisely for this reason. > > I am strongly opposed to any such advice, or to anything that > makes that advice necessary. > > Using NULL instead of 0 makes programs clearer, and is strongly > to be encouraged. In that case, NULL must be defined to be 0, nothing else. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 14:33 ` Joe Buck @ 1997-10-15 16:51 ` Per Bothner [not found] ` <199710152351.QAA02138.cygnus.egcs@cygnus.com> 1 sibling, 0 replies; 34+ messages in thread From: Per Bothner @ 1997-10-15 16:51 UTC (permalink / raw) To: Joe Buck; +Cc: egcs > In that case, NULL must be defined to be 0, nothing else. I can live with that, but it would be nice to a warning if NULL is used in an int context. Currently, __null is mapped into null_node, which (when -ansi is not specified) is basically basically (void*)0. I missed the early context of this discussion, but I gather this causes some problems, some of which are related to overloading. I suggest instead that null_node be 0 - the same value and type as integer_zero_node, but a different tree node. Then NULL would work identically to the literal 0. However, we can add a check when null_node is treated as an integer (such as assigning to a int function parameter), and print a warning in those cases. --Per Bothner Cygnus Solutions bothner@cygnus.com http://www.cygnus.com/~bothner ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <199710152351.QAA02138.cygnus.egcs@cygnus.com>]
* Re: linux libio status [not found] ` <199710152351.QAA02138.cygnus.egcs@cygnus.com> @ 1997-10-16 1:51 ` Jason Merrill 1997-10-16 12:58 ` Joe Buck 1997-10-16 12:58 ` Alexandre Oliva 0 siblings, 2 replies; 34+ messages in thread From: Jason Merrill @ 1997-10-16 1:51 UTC (permalink / raw) To: Per Bothner, egcs >>>>> Per Bothner <bothner@cygnus.com> writes: > Currently, __null is mapped into null_node, which (when -ansi is not > specified) is basically basically (void*)0. I missed the early > context of this discussion, but I gather this causes some problems, > some of which are related to overloading. I'm not aware of any problems with __null. If anyone has any overloading bugs involving __null, please send them in. There were certainly problems with making (void*)0 magic in general, which is why I replaced that with __null. I believe that NULL should be retrieved from stddef.h, as I outlined earlier. This will get the __null definition, which should work for everyone. Does anyone have any practical problems with this? Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-16 1:51 ` Jason Merrill @ 1997-10-16 12:58 ` Joe Buck 1997-10-17 12:53 ` Jason Merrill 1997-10-16 12:58 ` Alexandre Oliva 1 sibling, 1 reply; 34+ messages in thread From: Joe Buck @ 1997-10-16 12:58 UTC (permalink / raw) To: Jason Merrill; +Cc: bothner, egcs > I'm not aware of any problems with __null. If anyone has any overloading > bugs involving __null, please send them in. __null isn't a problem, though I don't know what it helps, because it is g++-specific. Since much of the code I write has to go through about four different C++ compilers, only one of which is g++, it's not something I could make use of. Since I never use NULL in my code, I don't care how you define it -- *unless* you use NULL in the standard headers in a way that breaks if some user defines NULL the wrong way. > I believe that NULL should be retrieved from stddef.h, as I outlined > earlier. This will get the __null definition, which should work for > everyone. Does anyone have any practical problems with this? We can't guarantee that some other header will not attempt to define NULL. On Red Hat Linux 4.2 (with libc 5.3.12+patches), several do; worse, they define it as (void *)0. True, they do '#ifndef NULL' -- but you have to make sure the headers appear in the right order. This all started when we tried to solve the problem of running on current Linux systems. Current Linux systems define NULL as (void*)0 . The only safe solution is to remove all use of NULL from all the libstdc++ headers. User code can safely use NULL if they get your stddef.h definition. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-16 12:58 ` Joe Buck @ 1997-10-17 12:53 ` Jason Merrill 0 siblings, 0 replies; 34+ messages in thread From: Jason Merrill @ 1997-10-17 12:53 UTC (permalink / raw) To: Joe Buck; +Cc: bothner, egcs >>>>> Joe Buck <jbuck@synopsys.com> writes: > We can't guarantee that some other header will not attempt to define > NULL. No, but we can override any such definition with an #undef, so it doesn't matter. Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-16 1:51 ` Jason Merrill 1997-10-16 12:58 ` Joe Buck @ 1997-10-16 12:58 ` Alexandre Oliva 1 sibling, 0 replies; 34+ messages in thread From: Alexandre Oliva @ 1997-10-16 12:58 UTC (permalink / raw) To: Jason Merrill; +Cc: Per Bothner, egcs Jason Merrill writes: >>>>>> Per Bothner <bothner@cygnus.com> writes: >> Currently, __null is mapped into null_node, which (when -ansi is not >> specified) is basically basically (void*)0. I missed the early >> context of this discussion, but I gather this causes some problems, >> some of which are related to overloading. > I'm not aware of any problems with __null. If anyone has any overloading > bugs involving __null, please send them in. There were certainly problems > with making (void*)0 magic in general, which is why I replaced that with > __null. There may not be overloading bugs related with that, because NULL is an implementation defined null pointer constant. However, since CD2 suggests that 0 and 0L are valid definitions of NULL, other compilers might prefer to use NULL as an integer value instead of using it as a null pointer constant. I mean: bool foo(void*) { return true; } bool foo(int) { return false; } bool bar() { return foo(NULL); } Should bar() return true or false? This is implementation defined. If an implementation defines NULL as 0 or even 0L, foo(int) would be selected, and the result would be false. However, if __null is implemented in g++ the way I think it is, foo(void*) would be selected. Both results might be surprising. Worse yet, sometimes overload resolution should fail. Suppose: void foo(void*); void foo(int *); Shouldn't calling foo(NULL) produce a compile-time error due to ambiguity? And what if the following declarations are given instead? void foo(bool); void foo(int*); This is all implementation defined, AFAIK. Maybe overload resolution should warn users if __null might have affected the result of the resolution. -- Alexandre Oliva mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org http://www.dcc.unicamp.br/~oliva Universidade Estadual de Campinas, SP, Brasil ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 11:12 ` Per Bothner 1997-10-15 14:33 ` Joe Buck @ 1997-10-15 16:51 ` Peter Seebach 1997-10-16 2:35 ` Make Money Fast (was: Re: linux libio status) Branko Cibej 1 sibling, 1 reply; 34+ messages in thread From: Peter Seebach @ 1997-10-15 16:51 UTC (permalink / raw) To: Per Bothner; +Cc: egcs In message < 199710151812.LAA15748@cygnus.com >, Per Bothner writes: >Joe Buck <jbuck@synopsys.com> writes: >> The comp.lang.c++ tells users "don't use NULL in C++ programming", >> precisely for this reason. >I am strongly opposed to any such advice, or to anything that >makes that advice necessary. Amen! >Using NULL instead of 0 makes programs clearer, and is strongly >to be encouraged. It also makes a non-empty set of programs *correct*. However, correctness aside, it is good to use NULL for null pointers, for the same reason it is good to use "hello, world" rather than { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd' } to initialize arrays of characters. (One point extra credit for spotting the difference, two points extra credit for spotting the case where the two are not different.) -s ^ permalink raw reply [flat|nested] 34+ messages in thread
* Make Money Fast (was: Re: linux libio status) 1997-10-15 16:51 ` Peter Seebach @ 1997-10-16 2:35 ` Branko Cibej 0 siblings, 0 replies; 34+ messages in thread From: Branko Cibej @ 1997-10-16 2:35 UTC (permalink / raw) To: Peter Seebach; +Cc: egcs Peter Seebach wrote: > However, correctness aside, it is good to use NULL for null pointers, > for the same reason it is good to use "hello, world" rather than > { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd' } > to initialize arrays of characters. > > (One point extra credit for spotting the difference, two points > extra credit for spotting the case where the two are not different.) Here you are, then: /* sizeof(diff1) == sizeof(diff2) + sizeof('\0') */ char diff1[] = "hello, world"; char diff2[] = { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd' }; /* sizeof(same1) == sizeof(same2) == sizeof(diff2) */ char same1[12] = "hello, world"; char same2[12] = { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd' }; (Who said you couldn't get free credit over the Net? :-) -- Branko Cibej <branko.cibej@hermes.si> HERMES SoftLab, Litijska 51, 1000 Ljubljana, Slovenia phone: (++386 61) 186 53 49 fax: (++386 61) 186 52 70 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 9:15 ` Joe Buck 1997-10-15 11:12 ` Per Bothner @ 1997-10-15 14:33 ` Richard Henderson 1 sibling, 0 replies; 34+ messages in thread From: Richard Henderson @ 1997-10-15 14:33 UTC (permalink / raw) To: Joe Buck; +Cc: Jason Merrill, egcs On Wed, Oct 15, 1997 at 08:51:29AM -0700, Joe Buck wrote: > The only other alternatives I can think of is to force a #define NULL 0, > or do some kind of mini-fixincludes on the existing libio.h header. > (The latter technique could solve the problems with the new lock functions > as well). The problem with the fixincludes option is that I ran into the same problem on RH Linux Alpha not because of <libio.h>, but one of the kernel header files. If we leave NULL in the installed C++ headers, redefining NULL is the only successful option. Which means in my mind: get it out. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status
@ 1997-10-15 12:10 Greg Galloway
1997-10-16 12:53 ` H.J. Lu
0 siblings, 1 reply; 34+ messages in thread
From: Greg Galloway @ 1997-10-15 12:10 UTC (permalink / raw)
To: egcs
I previously wrote:
> By the way strstream seems to be broken if you let it dynamically allocate
> it's own buffer. The following program gives a segmentation fault:
>
> #include <cstdlib>
> #include <string>
> #include <strstream.h>
> main()
> {
> ostrstream os;
> os << "testing " << 123 << ends;
> string s = os.str();
> exit(0);
> }
>
My previous problems with strstream and dynamically allocated buffers appears
to be gone.
Upon looking at the call trace in gdb this program goes into an infinite
recursion on the basic_string<> ctor until __builtin_new() finally dies
giving a segmentation fault.
Greg
----
Gregory L. Galloway
Research Scientist I
http://eoeml.gtri.gatech.edu/home/gregg/
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 12:10 Greg Galloway @ 1997-10-16 12:53 ` H.J. Lu 0 siblings, 0 replies; 34+ messages in thread From: H.J. Lu @ 1997-10-16 12:53 UTC (permalink / raw) To: Greg Galloway; +Cc: egcs > > I previously wrote: > > By the way strstream seems to be broken if you let it dynamically allocate > > it's own buffer. The following program gives a segmentation fault: > > > > #include <cstdlib> > > #include <string> > > #include <strstream.h> > > main() > > { > > ostrstream os; > > os << "testing " << 123 << ends; > > string s = os.str(); > > exit(0); > > } > > > > My previous problems with strstream and dynamically allocated buffers appears > to be gone. > > Upon looking at the call trace in gdb this program goes into an infinite > recursion on the basic_string<> ctor until __builtin_new() finally dies > giving a segmentation fault. That is a bug in basic_string. H.J. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status
@ 1997-10-15 12:10 Greg Galloway
1997-10-15 20:16 ` Joe Buck
1997-10-16 12:58 ` H.J. Lu
0 siblings, 2 replies; 34+ messages in thread
From: Greg Galloway @ 1997-10-15 12:10 UTC (permalink / raw)
To: egcs
Richard Henderson wrote:
> Joe Buck wrote:
> > We need to silence these warnings. For the NULL, I suggest a global
> > s/NULL/0/ in the C++ iostreams headers.
>
> That's a reasonable solution. In my version of the libio patches,
> I make _G_config.h undef and redefine NULL to avoid this problem.
>
> > I don't know where the missing declarations should go; perhaps HJ has
> > an idea.
>
> I worked around this for Linux/Alpha by providing versions of
> libc-lock.h and stdio-lock.h to install with the newly built library.
> Perhaps we do the same thing for Intel?
I worked around this by copying egcs-971009/libio/libio.h into
/usr/include/g++.
By the way strstream seems to be broken if you let it dynamically allocate
it's own buffer. The following program gives a segmentation fault:
#include <cstdlib>
#include <string>
#include <strstream.h>
main()
{
ostrstream os;
os << "testing " << 123 << ends;
string s = os.str();
exit(0);
}
This one used to work for me under gcc-2.7.2.1 but is also broken with egcs:
#include <cstdlib>
#include <string>
#include <strstream.h>
main()
{
char buf[100]
ostrstream os(buf, 100);
os << "testing " << 123 << ends;
string s = os.str();
exit(0);
}
Greg
----
Gregory L. Galloway
Research Scientist I
http://eoeml.gtri.gatech.edu/home/gregg/
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 12:10 Greg Galloway @ 1997-10-15 20:16 ` Joe Buck 1997-10-16 12:58 ` H.J. Lu 1 sibling, 0 replies; 34+ messages in thread From: Joe Buck @ 1997-10-15 20:16 UTC (permalink / raw) To: Greg Galloway; +Cc: egcs > > I worked around this for Linux/Alpha by providing versions of > > libc-lock.h and stdio-lock.h to install with the newly built library. > > Perhaps we do the same thing for Intel? > > I worked around this by copying egcs-971009/libio/libio.h into > /usr/include/g++. I don't believe that this is safe to do in general. If you're using the 5.3.12 libio you need the matching header. The problem is that some structures have changed; this may be the cause of your crashes described below. > By the way strstream seems to be broken if you let it dynamically allocate > it's own buffer. The following program gives a segmentation fault: > > #include <cstdlib> > #include <string> > #include <strstream.h> > main() > { > ostrstream os; > os << "testing " << 123 << ends; > string s = os.str(); > exit(0); > } The fault doesn't occur on Solaris; it may be a libio issue (possibly tweaked by your use of the wrong libio). > This one used to work for me under gcc-2.7.2.1 but is also broken with egcs: > > #include <cstdlib> > #include <string> > #include <strstream.h> > main() > { > char buf[100] > ostrstream os(buf, 100); > os << "testing " << 123 << ends; > string s = os.str(); > exit(0); > } Again, once I put in the missing semicolon I have no problem on Solaris. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 12:10 Greg Galloway 1997-10-15 20:16 ` Joe Buck @ 1997-10-16 12:58 ` H.J. Lu 1 sibling, 0 replies; 34+ messages in thread From: H.J. Lu @ 1997-10-16 12:58 UTC (permalink / raw) To: Greg Galloway; +Cc: egcs > > Richard Henderson wrote: > > Joe Buck wrote: > > > We need to silence these warnings. For the NULL, I suggest a global > > > s/NULL/0/ in the C++ iostreams headers. > > > > That's a reasonable solution. In my version of the libio patches, > > I make _G_config.h undef and redefine NULL to avoid this problem. > > > > > I don't know where the missing declarations should go; perhaps HJ has > > > an idea. > > > > I worked around this for Linux/Alpha by providing versions of > > libc-lock.h and stdio-lock.h to install with the newly built library. > > Perhaps we do the same thing for Intel? > > I worked around this by copying egcs-971009/libio/libio.h into > /usr/include/g++. That is one way to fix it. > > By the way strstream seems to be broken if you let it dynamically allocate > it's own buffer. The following program gives a segmentation fault: > > #include <cstdlib> > #include <string> > #include <strstream.h> > main() > { > ostrstream os; > os << "testing " << 123 << ends; > string s = os.str(); > exit(0); > } > > This one used to work for me under gcc-2.7.2.1 but is also broken with egcs: > > #include <cstdlib> > #include <string> > #include <strstream.h> > main() > { > char buf[100] > ostrstream os(buf, 100); > os << "testing " << 123 << ends; > string s = os.str(); > exit(0); > } Both work for me with libc 5.4.39. H.J. ^ permalink raw reply [flat|nested] 34+ messages in thread
* linux libio status @ 1997-10-14 23:23 Joe Buck 1997-10-15 0:06 ` Richard Henderson 1997-10-15 0:52 ` Olivier Galibert 0 siblings, 2 replies; 34+ messages in thread From: Joe Buck @ 1997-10-14 23:23 UTC (permalink / raw) To: egcs team Well, it looks like we *really* need to clean out the old $prefix/include/g++ before doing make install, because it seemed that everyone missed this problem ('cause they all had leftover headers that were getting used). Thanks to Mumit's suggestion, I blew away everything under $prefix and re-installed on my Linux Red Hat 4.2 box -- 971008 plus HJ's patch adding weak symbols. The good news is that the failing test posted here recently now passes. The problem is that we now get a number of warnings, even for "hello world". The problem is this: we are now using the /usr/include/libio.h rather than the one from egcs. The version included with Red Hat (libc 5.3.12) has the text #ifndef NULL #if !defined(__cplusplus) || defined(__GNUC__) #define NULL ((void*)0) #else #define NULL (0) #endif #endif Now, egcs has been fixed so that C++ no longer freely casts (void *)0 to other pointers, so this now gives lots of warnings. e.g. for "hello world", or ----- #include <iostream.h> main () { cout << "Hello, world\n"; } ----- In file included from /usr/local/egcs/include/g++/iostream.h:31, from hello.cc:1: /usr/local/egcs/include/g++/streambuf.h:394: warning: invalid type `void *' for default argument to `ios *' In file included from hello.cc:1: /usr/local/egcs/include/g++/iostream.h:50: warning: invalid type `void *' for default argument to `ostream *' /usr/local/egcs/include/g++/iostream.h: In method `int ostream::opfx()': /usr/local/egcs/include/g++/iostream.h:53: warning: implicit declaration of function `int _IO_flockfile(...)' /usr/local/egcs/include/g++/iostream.h: In method `void ostream::osfx()': /usr/local/egcs/include/g++/iostream.h:54: warning: implicit declaration of function `int _IO_funlockfile(...)' /usr/local/egcs/include/g++/iostream.h: At top level: /usr/local/egcs/include/g++/iostream.h:123: warning: invalid type `void *' for default argument to `ostream *' /usr/local/egcs/include/g++/iostream.h:230: warning: invalid type `void *' for default argument to `ostream *' If we force NULL to be 0 as in c++ -DNULL=0 hello.cc we are down to /usr/local/egcs/include/g++/iostream.h: In method `int ostream::opfx()': In file included from hello.cc:1: /usr/local/egcs/include/g++/iostream.h:53: warning: implicit declaration of function `int _IO_flockfile(...)' /usr/local/egcs/include/g++/iostream.h: In method `void ostream::osfx()': /usr/local/egcs/include/g++/iostream.h:54: warning: implicit declaration of function `int _IO_funlockfile(...)' We need to silence these warnings. For the NULL, I suggest a global s/NULL/0/ in the C++ iostreams headers. There is no reason to write NULL, it is just a source of problems like this (*especially* since we have changed C++ to be strict about void*). I don't know where the missing declarations should go; perhaps HJ has an idea. One possibility is to just define them to null when the older library is in use. The new libio.h could have its locking functions split off into a new header, which always gets installed. Or something; I'm sure HJ and/or Ulrich have better ideas. Joe ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-14 23:23 Joe Buck @ 1997-10-15 0:06 ` Richard Henderson 1997-10-15 0:52 ` Olivier Galibert 1 sibling, 0 replies; 34+ messages in thread From: Richard Henderson @ 1997-10-15 0:06 UTC (permalink / raw) To: Joe Buck; +Cc: egcs team On Tue, Oct 14, 1997 at 11:23:49PM -0700, Joe Buck wrote: > We need to silence these warnings. For the NULL, I suggest a global > s/NULL/0/ in the C++ iostreams headers. That's a reasonable solution. In my version of the libio patches, I make _G_config.h undef and redefine NULL to avoid this problem. > I don't know where the missing declarations should go; perhaps HJ has > an idea. I worked around this for Linux/Alpha by providing versions of libc-lock.h and stdio-lock.h to install with the newly built library. Perhaps we do the same thing for Intel? r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-14 23:23 Joe Buck 1997-10-15 0:06 ` Richard Henderson @ 1997-10-15 0:52 ` Olivier Galibert 1997-10-15 11:12 ` Joe Buck ` (2 more replies) 1 sibling, 3 replies; 34+ messages in thread From: Olivier Galibert @ 1997-10-15 0:52 UTC (permalink / raw) To: egcs team On Tue, Oct 14, 1997 at 11:23:49PM -0700, Joe Buck wrote: > We need to silence these warnings. For the NULL, I suggest a global > s/NULL/0/ in the C++ iostreams headers. There is no reason to write > NULL, it is just a source of problems like this (*especially* since > we have changed C++ to be strict about void*). Don't use '0' but '0L'. This way you will be OK with NULL in stdargs when int=32b and pointer=64b. OG. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 0:52 ` Olivier Galibert @ 1997-10-15 11:12 ` Joe Buck 1997-10-15 12:10 ` Olivier Galibert 1997-10-15 11:12 ` Peter Seebach [not found] ` <199710151419.JAA20162.cygnus.egcs@monolith.solon.com> 2 siblings, 1 reply; 34+ messages in thread From: Joe Buck @ 1997-10-15 11:12 UTC (permalink / raw) To: Olivier Galibert; +Cc: egcs > > On Tue, Oct 14, 1997 at 11:23:49PM -0700, Joe Buck wrote: > > We need to silence these warnings. For the NULL, I suggest a global > > s/NULL/0/ in the C++ iostreams headers. There is no reason to write > > NULL, it is just a source of problems like this (*especially* since > > we have changed C++ to be strict about void*). > > Don't use '0' but '0L'. This way you will be OK with NULL in stdargs > when int=32b and pointer=64b. And you'll be broken on platforms where sizeof(long) != sizeof(pointer), or at least you would if it weren't for the fact that C++ requires prototypes for all functions. Remember, we are talking about C++ here, not C. Stroustrup says (The C++ Programming Language, 3rd Edition, p. 88) "Because of C++'s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel that you must define NULL, use const int NULL = 0; ..." There is a similar discussion in the comp.lang.c++ FAQ. In C++, there are always prototypes. Thus 0 or 0L makes no difference, and in fact the "standard null pointer" is essentially 0 in C++. The argument is coerced to the proper pointer. However, standard C++ does not let you convert (void *) to (T *) without a cast, so defining NULL as (void *)0 is completely broken in C++. It used to work in g++, but that was an extension (furthermore this extension prevented g++ from implementing the standard overloading rules correctly). Hence The only exception is functions with ... in their spec. Here, neither 0 nor 0L will result in portable code. Your suggestion switches the erroneous assumption that sizeof(T *) == sizeof(int) with another erroneous assumption, that sizeof(T *) == sizeof(long). Worse, you leave users with the idea that they can safely use NULL for any null pointer type, even in variadic functions. Sorry, you can't do that in standard C++. For variadic functions, users must declare any optional arguments correctly, period. Conclusion: we should deprecate the use of NULL in C++ code. If we must define NULL for C++ code, it must be 0. Nothing else. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 11:12 ` Joe Buck @ 1997-10-15 12:10 ` Olivier Galibert 1997-10-15 20:16 ` Joe Buck 0 siblings, 1 reply; 34+ messages in thread From: Olivier Galibert @ 1997-10-15 12:10 UTC (permalink / raw) To: Joe Buck; +Cc: egcs On Wed, Oct 15, 1997 at 09:04:20AM -0700, Joe Buck wrote: > > Don't use '0' but '0L'. This way you will be OK with NULL in stdargs ^^^^^^^ > > when int=32b and pointer=64b. I was explicitely talking about functions with '...' in them. > The only exception is functions with ... in their spec. Here, neither 0 > nor 0L will result in portable code. Your suggestion switches the > erroneous assumption that sizeof(T *) == sizeof(int) with another > erroneous assumption, that sizeof(T *) == sizeof(long). Worse, you leave > users with the idea that they can safely use NULL for any null pointer > type, even in variadic functions. Sorry, you can't do that in standard > C++. For variadic functions, users must declare any optional arguments > correctly, period. > > Conclusion: we should deprecate the use of NULL in C++ code. If we > must define NULL for C++ code, it must be 0. Nothing else. You say "make sure that current code works but randomly crashes when the users upgrade to new 64bits architectures". I don't call that being fair to the user. The current existing architectures I know about are: - 32bits int, 32bits long, 64bits long long, 32bits ptr - 32bits int, 64bits long, 64bits long long, 64bits ptr The first one concerns almost all unixes. The second is relevant in Irix 6 and on alphas. Other probably exist but are an order of magnitude less present. Besides, the probability is high that most of the code works if sizeof(T *)<=sizeof(NULL). This depends on parameter-passing conventions. Code can't work with sizeof(T *)>sizeof(NULL). If your vision of "deprecating NULL" is "let users having their code working right now but crashing randomly when they eventually have the money to buy a 64bits processor" then yes, define NULL as 0. If you want to be as nice as possible to the user while not changing the compiler, define it as 0L. If you really want to deprecate it define it at __null, make it behave the right way w.r.t type conversions and warn when used as parameter in a varadic function or in constructions like "int a=NULL;". OG. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 12:10 ` Olivier Galibert @ 1997-10-15 20:16 ` Joe Buck 1997-10-15 20:16 ` Olivier Galibert 0 siblings, 1 reply; 34+ messages in thread From: Joe Buck @ 1997-10-15 20:16 UTC (permalink / raw) To: Olivier Galibert; +Cc: jbuck, egcs > > Conclusion: we should deprecate the use of NULL in C++ code. If we > > must define NULL for C++ code, it must be 0. Nothing else. > > > You say "make sure that current code works but randomly crashes when the > users upgrade to new 64bits architectures". I don't call that being > fair to the user. Stop putting words in my mouth. Since my C++ code has to run with multiple compilers, I never use NULL and, on those rare occasions where I must use a variadic function, I pass a null pointer of the right type. What's unfair to the user is to tell the user he/she can use NULL in any position where a pointer is required in C++ code. The problem is that there is no definition that will work correctly and portably with variadic functions. (But then, variadic functions are a bad idea, as their arguments can't be type-checked at compile time except by special means, like the gcc printf hack. Furthermore, they are rare except for the printf family, and gcc has a special check for those). > If your vision of "deprecating NULL" is "let users having their code working > right now but crashing randomly when they eventually have the money to buy > a 64bits processor" then yes, define NULL as 0. So Stroustrup doesn't know what he's talking about? So every C++ author in the book doesn't know either? For variadic functions that want a pointer, 0L is just as broken as 0; on certain memory models for 16-bit PC code, you will corrupt your stack (a near pointer, only 16 bits, is expected and you push a four-byte quantity). There's no substitute for programming correctly. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 20:16 ` Joe Buck @ 1997-10-15 20:16 ` Olivier Galibert 1997-10-16 12:53 ` Pal Engstad 0 siblings, 1 reply; 34+ messages in thread From: Olivier Galibert @ 1997-10-15 20:16 UTC (permalink / raw) To: Joe Buck; +Cc: egcs On Wed, Oct 15, 1997 at 11:43:02AM -0700, Joe Buck wrote: > There's no substitute for programming correctly. I think I wasn't clear enough. I completely agree with 95% of what you said. The only point I disagree with is "we must #define NULL 0 because Stroustrup said so". Without adding special support for a __null keyword or whatever, we have only two reasonable possibilities for NULL which are 0 and 0L. The choice between them is without a real impact except in the case of passing NULL in a varadic function call with the old C meaning (void *)0. Telling "Thou shan't use NULL in such calls" is irrelevant. I know better than using them, but we're in the real world and anyway it was perfectly valid one or two years ago when implicitely converting from (void *) wasn't yet ruled out. Which means we have a lot of code floating around which requires passing such a NULL to work. Just for the record xemacs was in this case some months ago. Now, what should we do ? We can't without additional support warn for such code. Besides, would we be able to warn that we could be _sure_ to do the Right Thing in all cases, i.e. implicitely use a (void *)0. I don't think gcc supports multisized pointers anyway. We can't even make a choice which will lend to crashes in most of the current platforms since they are 32/32/32 (int/long/pointer) and the distinction between int and long doesn't exist in our case. Given this situation I really think that the only fair approach is the ensure that for most of the people the code will keep working in the future. Now, the new architectures are 32/32/64, 32/64/32 and 32/64/64. 32/32/64 is hosed, both choices will lend to crashes. 32/64/32 will almost always work with NULL=0, and will work on a lot of architectures with NULL=0L. 32/64/64 (which are the irix 6 and dec alpha cases, I know no real-world implementations of the previous two) will almost always work with NULL=0L and never work with NULL=0. The "almost always" comes from the fact that some calling conventions separate "data" and "pointers" and so no integer type will do for a pointer. This means we have the choice between using 0 and crashing badly on current 64bits architectures but working on some weird ones, or using 0L and working on these real architectures while keeping a fair chance to work on the weird ones. Conclusion: we're here to help people make programs, not implementing language non-normative politics. OG. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 20:16 ` Olivier Galibert @ 1997-10-16 12:53 ` Pal Engstad 0 siblings, 0 replies; 34+ messages in thread From: Pal Engstad @ 1997-10-16 12:53 UTC (permalink / raw) To: Olivier Galibert; +Cc: Joe Buck, egcs Olivier Galibert wrote: > Conclusion: we're here to help people make programs, not implementing > language non-normative politics. > Following this thread, the discussion is on the macro NULL. From the Draft working paper it is said: C.4.2.3 Macro NULL 1 The macro NULL, defined in any of <clocale>, <cstddef>, <cstdio>, <cstring>, <ctime>t, or <cwchar>, is an implementation-defined C++ null-pointer constant in this International Standard (18.1) 254) 254) Possible definitions include 0 and 0L, but not (void *)0. Given this, it is evident that the choise is either 0 or 0L. I believe it should be given in accordance with what fits best with the architecture it is on. I.e.: If the target has 32 bit int and 32 bit pointers, it should be 0. If the target has 64 bit longs and 64 bit pointers it should be 0L, and so on. PKE. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 0:52 ` Olivier Galibert 1997-10-15 11:12 ` Joe Buck @ 1997-10-15 11:12 ` Peter Seebach 1997-10-15 20:16 ` Joe Buck [not found] ` <199710151419.JAA20162.cygnus.egcs@monolith.solon.com> 2 siblings, 1 reply; 34+ messages in thread From: Peter Seebach @ 1997-10-15 11:12 UTC (permalink / raw) To: egcs team In message < 19971015095211.03621@renaissance.loria.fr >, Olivier Galibert writes : >On Tue, Oct 14, 1997 at 11:23:49PM -0700, Joe Buck wrote: >> We need to silence these warnings. For the NULL, I suggest a global >> s/NULL/0/ in the C++ iostreams headers. There is no reason to write >> NULL, it is just a source of problems like this (*especially* since >> we have changed C++ to be strict about void*). >Don't use '0' but '0L'. This way you will be OK with NULL in stdargs >when int=32b and pointer=64b. Assuming, of course, that 0L is 64 bits. Rumor has it that some implementations chose to make int and long 32, pointer 64, and (cough) "long long" 64. Further, what of an implementation where long is *larger* than a pointer, but int is the same size? Then you need 0, not 0L... The only correct way to pass null pointers to stdarg functions is with a cast to the type of pointer the function will be looking for. Probably a misfeature, but history doesn't always favor elegance. It would have been a little easier if C89 had ruled that NULL must actually have pointer type, then you could just use it for anything that would be taking arguments as (void *), and, if you're feeling courageous and not-quite-perfectly-portable, you could just use it for all the pointers... -s ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 11:12 ` Peter Seebach @ 1997-10-15 20:16 ` Joe Buck 0 siblings, 0 replies; 34+ messages in thread From: Joe Buck @ 1997-10-15 20:16 UTC (permalink / raw) To: Peter Seebach; +Cc: egcs > It would have been a little easier if C89 had ruled that NULL must > actually have pointer type, then you could just use it for anything > that would be taking arguments as (void *), and, if you're feeling > courageous and not-quite-perfectly-portable, you could just use it > for all the pointers... The problem is that C didn't think out this pointer stuff well enough. The main breakage was to say that (void *) can be assigned to any pointer type. But that confuses several types of pointers together into one mishmash. There are certain distinguished pointer types not directly reflected in the language: -- the null pointer -- a "maximally aligned" pointer, as returned by malloc Such objects can be legally assigned to any pointer type. Then there is another beast, the pointer to unknown data object. We can't say anything about its alignment. The problem is that C decided to make all of these beasts (void *) and permit free casting. What if there were a new type, aligned_pointer_t. malloc would return one of these. We can safely convert an aligned_pointer to any type of pointer, so no cast is needed. Any cast in the reverse direction would be system-dependent, so a cast is needed. Similarly, any pointer can be converted to void *, but neither C nor C++ would allow conversion of (void *) to another type of pointer without a cast. Then NULL could be (aligned_pointer_t)0, and this could work in C or C++. ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <199710151419.JAA20162.cygnus.egcs@monolith.solon.com>]
* Re: linux libio status [not found] ` <199710151419.JAA20162.cygnus.egcs@monolith.solon.com> @ 1997-10-15 16:51 ` Jason Merrill 1997-10-15 20:16 ` Peter Seebach 1997-10-16 15:19 ` Paul Koning 0 siblings, 2 replies; 34+ messages in thread From: Jason Merrill @ 1997-10-15 16:51 UTC (permalink / raw) To: Peter Seebach, egcs >>>>> Peter Seebach <seebs@monolith.solon.com> writes: > In message < 19971015095211.03621@renaissance.loria.fr >, Olivier Galibert writes > : >> On Tue, Oct 14, 1997 at 11:23:49PM -0700, Joe Buck wrote: >>> We need to silence these warnings. For the NULL, I suggest a global >>> s/NULL/0/ in the C++ iostreams headers. There is no reason to write >>> NULL, it is just a source of problems like this (*especially* since >>> we have changed C++ to be strict about void*). >> Don't use '0' but '0L'. This way you will be OK with NULL in stdargs >> when int=32b and pointer=64b. > Assuming, of course, that 0L is 64 bits. Rumor has it that some > implementations chose to make int and long 32, pointer 64, and > (cough) "long long" 64. > Further, what of an implementation where long is *larger* than a > pointer, but int is the same size? Then you need 0, not 0L... This is why we have a NULL macro. The gcc stddef.h provides an appropriate definition, so we can put #undef NULL #define __need_NULL #include <stddef.h> #undef __need_NULL somewhere strategic, and that should do the trick. > It would have been a little easier if C89 had ruled that NULL must > actually have pointer type, then you could just use it for anything > that would be taking arguments as (void *), and, if you're feeling > courageous and not-quite-perfectly-portable, you could just use it > for all the pointers... C89 may not have, but gcc defines it that way. Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 16:51 ` Jason Merrill @ 1997-10-15 20:16 ` Peter Seebach 1997-10-15 22:29 ` Jason Merrill 1997-10-16 15:19 ` Paul Koning 1 sibling, 1 reply; 34+ messages in thread From: Peter Seebach @ 1997-10-15 20:16 UTC (permalink / raw) To: Jason Merrill; +Cc: egcs In message < u9zpoarh0w.fsf@yorick.cygnus.com >, Jason Merrill writes: >This is why we have a NULL macro. The gcc stddef.h provides an appropriate >definition, so we can put >#undef NULL >#define __need_NULL >#include <stddef.h> >#undef __need_NULL >somewhere strategic, and that should do the trick. Well, strictly speaking, I don't think that's correct - I *believe* a user who has not included <stddef.h> is allowed to assume that not everything in it is defined. I think an implementation is obliged to have the common declaration of NULL, if there is one, be in some other header included by <stddef.h> and friends. >C89 may not have, but gcc defines it that way. Well, yeah, but that's not very useful to a person writing code not exclusively for use with one compiler... :) -s ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 20:16 ` Peter Seebach @ 1997-10-15 22:29 ` Jason Merrill 1997-10-16 8:31 ` Peter Seebach 0 siblings, 1 reply; 34+ messages in thread From: Jason Merrill @ 1997-10-15 22:29 UTC (permalink / raw) To: Peter Seebach; +Cc: egcs >>>>> Peter Seebach <seebs@monolith.solon.com> writes: > In message < u9zpoarh0w.fsf@yorick.cygnus.com >, Jason Merrill writes: >> This is why we have a NULL macro. The gcc stddef.h provides an appropriate >> definition, so we can put >> #undef NULL >> #define __need_NULL >> #include <stddef.h> >> #undef __need_NULL >> somewhere strategic, and that should do the trick. > Well, strictly speaking, I don't think that's correct - I *believe* a > user who has not included <stddef.h> is allowed to assume that not everything > in it is defined. That's why we define __need_NULL. That tells the gcc stddef.h that we only want the definition of NULL, and nothing else. Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 22:29 ` Jason Merrill @ 1997-10-16 8:31 ` Peter Seebach 1997-10-16 15:19 ` Jason Merrill 0 siblings, 1 reply; 34+ messages in thread From: Peter Seebach @ 1997-10-16 8:31 UTC (permalink / raw) To: Jason Merrill; +Cc: egcs In message < u9oh4q46ox.fsf@yorick.cygnus.com >, Jason Merrill writes: >That's why we define __need_NULL. That tells the gcc stddef.h that we only >want the definition of NULL, and nothing else. Isn't that an order of magnitude more complicated than providing <null.h>, and having everything that needs NULL include it? -s ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-16 8:31 ` Peter Seebach @ 1997-10-16 15:19 ` Jason Merrill 1997-10-16 12:53 ` Peter Seebach 0 siblings, 1 reply; 34+ messages in thread From: Jason Merrill @ 1997-10-16 15:19 UTC (permalink / raw) To: Peter Seebach; +Cc: egcs >>>>> Peter Seebach <seebs@monolith.solon.com> writes: > In message < u9oh4q46ox.fsf@yorick.cygnus.com >, Jason Merrill writes: >> That's why we define __need_NULL. That tells the gcc stddef.h that we only >> want the definition of NULL, and nothing else. > Isn't that an order of magnitude more complicated than providing > <null.h>, and having everything that needs NULL include it? Do you also want to provide <size_t.h>, <ptrdiff_t.h>, <wchar_t.h> and <wint_t.h>? It doesn't seem excessively complicated to me, since the user doesn't have to deal with it and we only have to do it once. Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-16 15:19 ` Jason Merrill @ 1997-10-16 12:53 ` Peter Seebach 0 siblings, 0 replies; 34+ messages in thread From: Peter Seebach @ 1997-10-16 12:53 UTC (permalink / raw) To: Jason Merrill; +Cc: egcs In message < u9iuux4tpv.fsf@yorick.cygnus.com >, Jason Merrill writes: >> Isn't that an order of magnitude more complicated than providing >> <null.h>, and having everything that needs NULL include it? >Do you also want to provide <size_t.h>, <ptrdiff_t.h>, <wchar_t.h> and ><wint_t.h>? It doesn't seem excessively complicated to me, since the user >doesn't have to deal with it and we only have to do it once. Hmm. I would have to actually go look up where else each of those is defined... In general, I think at least half of it isn't even the namespace, but just intrinsic distrust of a scheme where one header makes use of a clearly magic internal of another header... Dangerous magic, that. (It's probably also mildly inefficient, but on modern machines, who cares if one compiler is three times as slow as another?) -s ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: linux libio status 1997-10-15 16:51 ` Jason Merrill 1997-10-15 20:16 ` Peter Seebach @ 1997-10-16 15:19 ` Paul Koning 1 sibling, 0 replies; 34+ messages in thread From: Paul Koning @ 1997-10-16 15:19 UTC (permalink / raw) To: jason; +Cc: egcs >>>>> "Jason" == Jason Merrill <jason@cygnus.com> writes: >>>>> Peter Seebach <seebs@monolith.solon.com> writes: Peter >> It would have been a little easier if C89 had ruled that NULL must Peter >> actually have pointer type, then you could just use it for Peter >> anything that would be taking arguments as (void *), and, if Peter >> you're feeling courageous and not-quite-perfectly-portable, you Peter >> could just use it for all the pointers... Jason> C89 may not have, but gcc defines it that way. Hm... I have seen some "code" that contains statements of the form: int i = NULL; and while I wouldn't want to work anywhere near the "programmer" who wrote that, it does appear to compile with some of the compilers that are currently out in the world... paul ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~1997-10-17 12:53 UTC | newest] Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <199710150623.XAA06491.cygnus.egcs@atrus.synopsys.com> 1997-10-15 2:10 ` linux libio status Jason Merrill 1997-10-15 9:15 ` Joe Buck 1997-10-15 11:12 ` Per Bothner 1997-10-15 14:33 ` Joe Buck 1997-10-15 16:51 ` Per Bothner [not found] ` <199710152351.QAA02138.cygnus.egcs@cygnus.com> 1997-10-16 1:51 ` Jason Merrill 1997-10-16 12:58 ` Joe Buck 1997-10-17 12:53 ` Jason Merrill 1997-10-16 12:58 ` Alexandre Oliva 1997-10-15 16:51 ` Peter Seebach 1997-10-16 2:35 ` Make Money Fast (was: Re: linux libio status) Branko Cibej 1997-10-15 14:33 ` linux libio status Richard Henderson 1997-10-15 12:10 Greg Galloway 1997-10-16 12:53 ` H.J. Lu -- strict thread matches above, loose matches on Subject: below -- 1997-10-15 12:10 Greg Galloway 1997-10-15 20:16 ` Joe Buck 1997-10-16 12:58 ` H.J. Lu 1997-10-14 23:23 Joe Buck 1997-10-15 0:06 ` Richard Henderson 1997-10-15 0:52 ` Olivier Galibert 1997-10-15 11:12 ` Joe Buck 1997-10-15 12:10 ` Olivier Galibert 1997-10-15 20:16 ` Joe Buck 1997-10-15 20:16 ` Olivier Galibert 1997-10-16 12:53 ` Pal Engstad 1997-10-15 11:12 ` Peter Seebach 1997-10-15 20:16 ` Joe Buck [not found] ` <199710151419.JAA20162.cygnus.egcs@monolith.solon.com> 1997-10-15 16:51 ` Jason Merrill 1997-10-15 20:16 ` Peter Seebach 1997-10-15 22:29 ` Jason Merrill 1997-10-16 8:31 ` Peter Seebach 1997-10-16 15:19 ` Jason Merrill 1997-10-16 12:53 ` Peter Seebach 1997-10-16 15:19 ` Paul Koning
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).