[Bug libstdc++/25191] exception_defines.h #defines try/catch
--- Comment #62 from l dot lunak at suse dot cz 2008-11-19 22:41 --- (In reply to comment #60) > -fno-exceptions is a big hammer. It will break exceptions trying to > pass through code compiled with that flag whether or not that code has > any try/catch constructs. If you might have some code that throws, you > shouldn't use -fno-exceptions; that's what broke your package. In that case I suggest you remove -fno-exceptions altogether, because it's virtually impossibly for any non-trivial C++ application to make sure it doesn't use any code that might throw, starting with operator new. Sorry, but it's about as sensible argument as yours. Let me put it simply: -fno-exceptions is an optimization that saves generating code that would not be used, in line with the C++ rule of not paying for what one does not use. So it simply makes sense to use it in projects (or parts thereof) that do no use exceptions in order to get some savings (does somebody use -fno-exceptions in any other way?). Now, such code calls code from elsewhere that may throw, and so the programmer uses also try-catch, but does not actually test that specific part, since a) it's trivial code, b) he's too busy and we're just people, c) getting an exception should be exceptional. And we have perfectly fine code that compiles, but, when it eventually comes, does not work. It may not happen in your perfect world but in the real one it does. > Getting an error on try would have helped you find that problem, but that > doesn't mean it's the right answer for all situations; And what other situations are there, except for people who write code with exception handling, who make sure it works even without exceptions, who are too lazy to run sed few times, who will be explicitly aware of this and who presumably will be just a handful of people in total compared to the rest? What's the problem with giving these people -fstrip-exceptions or whatever and leaving the rest as it is (with fixing libstdc++)? > if I'm writing > code that may be used by other programs, I should write it to be > exception-safe even if I don't throw any exceptions myself. Irrelevant, this is the other way around. > Perhaps we could just warn once if we see try/catch outside library > headers with -fno-exceptions. I'd love to live in your perfect world. Sadly, I don't, so I'm looking forward to having to take care of code that will not have -Wexceptions in its flag (since it needs to be explicitly enabled, right?) or where one warning will get easily overlooked for whatever reason. I really fail to see what's so complicated about not letting one shoot themselves in the foot just because of lazy people with special needs. Thanks for trying, anyway. -- l dot lunak at suse dot cz changed: What|Removed |Added -------- CC|l dot lunak at suse dot cz | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191
[Bug libstdc++/25191] exception_defines.h #defines try/catch
--- Comment #34 from l dot lunak at suse dot cz 2007-04-24 10:54 --- I think the reason why the discussion here is so complicated is that you libstdc++ people are, because of exception_defines.h, confused about what -fno-exceptions actually does. From comment #15: "Then, why what is this PR is about in the first place? -fno-exceptions turns try/catch into macros with specified semantics." That's clearly not true. It is libstdc++ that changes the try/catch keywords into macros and _changes_ their semantics. Also, again from comment #15: "It is also a simple fact that GCC documents what happens with -fno-exceptions." - Sorry, but where? The info/man pages only say "You may also wish to disable this option if you are compiling older C++ programs that don't use exception handling.", but it doesn't say anything more about -fno-exceptions. What -fno-exceptions does (when libstdc++ is not used) is that it disables exceptions support. If any code requiring exceptions support is actually used, an error is generated (try compiling the testcase from comment #4 with -fno-exceptions and without the include). This is the same like when asking for full ANSI compliance when compiling and using GNU extensions in the code. What libstdc++ does is that it (silently, to make it even worse) globally changes the semantics of the try/catch keywords, preventing the compiler from producing the error message and changing the behaviour of the compiled code, which may lead to incorrect results. Comment #2 also doesn't hold much of value, since if libstdc++ tries to be as much conforming as possible, why does it change semantics of C++ keywords? Also, if you argue against __try/__catch, why do you already use __throw_exception_again, which is just a different name for throw? If you can use this, you can as well use __try and __catch. Since try/catch can be redefined, try and catch used in the libstdc++ code clearly are not the actual normal C++ keywords. Please do as the original comment says and use __try/__catch instead of changing semantics of C++ keywords. What libstdc++ now does is very clearly a bug. The severity of this bug should be also raised since this bug can silently change code behaviour of any code using libstdc++. -- l dot lunak at suse dot cz changed: What|Removed |Added CC| |l dot lunak at suse dot cz http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191
[Bug libstdc++/25191] exception_defines.h #defines try/catch
--- Comment #39 from l dot lunak at suse dot cz 2007-04-27 14:41 --- I find the reasoning that this change should not be done because somebody possibly might be using the libstdc++'s different semantics of try/catch rather weak, for several reasons: - it's not documented anywhere, at least I haven't found any such docs, so it's internal undocumented feature - if somebody actually uses it, then they can simply switch to __try/__catch and be done with it; additionally compared to users who want normal try/catch keywords they have the advantage that the compiler will detect the problem, while with the current changed try/catch there's absolutely no detection besides non-working code - finally, I find it very unlikely that there actually would be people using try/catch in the way libstdc++ does. You cannot "just not generate the heavy exception machinery" and hope it works. Code that explicitly uses exceptions relies on them, just like e.g. code using explicit NULL pointer checks relies on them. You cannot silently remove all "if( pointer == NULL )" checks in code and hope it works, because that would avoid error recovery code. The same way silently dumping catch blocks means dumping error recovery code. Libstc++ can work this way because it doesn't use exceptions on its own, it just has the try/catch #defines to be able to work with code both using and not using them. In general if somebody wants to write code not using exceptions they can simply not use them. Special cases like libstdc++ are special and people doing that should better known what they're doing. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191
[Bug libstdc++/25191] exception_defines.h #defines try/catch
--- Comment #56 from l dot lunak at suse dot cz 2008-09-24 08:50 --- (In reply to comment #55) > It seems reasonable to me for try { X } catch... to mean X when > -fno-exceptions. We don't need to error except on throw. It seems unreasonable to me that gcc would silently modify code's behaviour, just like it would be unreasonable that -pedantic would silently change 'long long i = 2LL << 34;' to 'long i = 0;'. With today's complex build systems it is not that difficult to get -fno-exceptions without noticing and then get code that works differently than intended (and I'm not making this up, I had such a real case). If people really want code with exception handling to work with both -fexception states, then they need to write the code with that in mind and then they can as well just use __try/__catch macros the way libstdc++ does now, just without breaking the code for the rest of people who can run into trouble if the compiler/libraries try to outguess them. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191
[Bug libstdc++/25191] exception_defines.h #defines try/catch
--- Comment #59 from l dot lunak at suse dot cz 2008-09-25 09:56 --- (In reply to comment #58) > >> It seems reasonable to me for try { X } catch... to mean X when > >> -fno-exceptions. We don't need to error except on throw. > > > > It seems unreasonable to me that gcc would silently modify code's behaviour, > > The change I was talking about doesn't modify behavior. If there are no > exceptions, catch blocks will never be executed, so we can optimize them > away in the presence of -fno-exceptions. But only in your perfect world. This bug and its silent discarding of exception handling code (and an unintended -fno-exception from the build system) made us release a broken package. If you want to add support for discarding of explicitly written exceptions code, ok, whatever, but please make it explicit, because having it the way it is with this bug is rather pointless (since then either you don't use exceptions at all and then there's no need to write the exception handling code, or you mix it and then you soon may find it simpler to drop the -fno-exception rather than explicitly check all code paths after you refactor something). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25191
[Bug c++/35669] New: NULL (__null) not considered different from 0 with C++
When compiling with g++, the various error checking gained from using NULL instead of plain 0 for the null pointer does not work. For example $ cat a.c #include void foo( int a ) { printf( "INT\n" ); } int main() { foo( NULL ); foo( 0 ); int a = NULL; return 0; } $ gcc -Wall a.c a.c: In function main: a.c:10: warning: passing argument 1 of foo makes integer from pointer without a cast a.c:12: warning: initialization makes integer from pointer without a cast a.c:12: warning: unused variable a $ g++ -Wall a.c a.c: In function int main(): a.c:12: warning: unused variable a As can be seen, compiling as C++ does not detect the mistakes in the code. The compiler uses __null though, as can be seen in preprocessed code: $ g++ -Wall -E a.c | tail { printf( "INT\n" ); } int main() { foo( __null ); foo( 0 ); int a = __null; } $ gcc -v Using built-in specs. Target: i586-suse-linux Configured with: ../configure --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.3 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --with-slibdir=/lib --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --program-suffix=-4.3 --enable-version-specific-runtime-libs --enable-linux-futex --without-system-libunwind --with-cpu=generic --build=i586-suse-linux Thread model: posix gcc version 4.3.0 (SUSE Linux) The problem already exists with gcc 4.2.1, but gcc 4.1.2 (specifically "gcc version 4.1.2 20070115 (prerelease) (SUSE Linux)") works fine and reports: $ g++ -Wall a.c a.c: In function int main(): a.c:10: warning: passing NULL to non-pointer argument 1 of void foo(int) a.c:12: warning: converting to non-pointer type int from NULL a.c:12: warning: unused variable a -- Summary: NULL (__null) not considered different from 0 with C++ Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: l dot lunak at suse dot cz http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35669
[Bug c++/35669] NULL (__null) not considered different from 0 with C++
--- Comment #2 from l dot lunak at suse dot cz 2008-03-22 23:15 --- When you say the warning is wrong, you presumably mean "passing argument 1 of foo makes integer from pointer without a cast", but this bugreport is about (the absence of) "passing NULL to non-pointer argument 1 of void foo(int)", which is a valid warning. I think nobody in their right mind would try to feed NULL to foo(int), they should use 0 if they want an integer - why would NULL be __null then instead of 0? Using -Wconversion helps with getting the warning, but it also causes warnings for normal common things like foo(2*0.5). While foo(NULL) is almost certainly a bug somewhere (and I saw such one for real myself), foo(2*0.5) is quite common, almost always harmless, and would require making the code more ugly by using explicit casts. Would it be possible to get a warning about an almost certain bug without many warnings about something almost certainly harmless? -- l dot lunak at suse dot cz changed: What|Removed |Added Severity|normal |enhancement Status|RESOLVED|UNCONFIRMED Resolution|WORKSFORME | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35669
[Bug c++/35669] NULL (__null) not considered different from 0 with C++
--- Comment #6 from l dot lunak at suse dot cz 2008-03-23 20:16 --- > Hmm, 2*0.5 should be folded pretty early so Wconversion should see 1.0 which > can be converted exactly to an integer (I think), so there should be no > warning whatsoever. Are you sure you are using GCC 4.3? I cannot reproduce > the warning. I didn't realize gcc could optimize this example. It was just meant to be an example of passing any float to foo(int). Make that foo(M_PI*10), foo(1.2), foo(sin(bar)*100) or whatever. My point was that calling foo(int) as foo(var) with var being a float is quite common code, whereas foo(NULL) is a mistake (or brain-damage :) ). Therefore I'd like a way to get warned only about the latter but not the sooner, which -Wconversion is not. That is why I changed this to an enhancement after being told that -Wall not warning about foo(NULL) is not a bug. > > True. So, is there any example where use of NULL / __null in a non-pointer > > context is a good idea? > > Is there an example where it leads to bugs? Yes. Consider you have code like this: void foo(void* bar); // a function somewhere ... foo( NULL ); // you call it ... Now consider you want to add an overload foo(int). Now everybody who called the original version as foo(0) is suddenly calling a different function, but I intentionally used NULL to express I'm passing a null pointer, so I expect at least a warning (and without all the stuff I'd get with -Wconversion). And this example is actually based on a real problem that I had to debug in KDE libraries. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35669
[Bug c++/35669] NULL (__null) not considered different from 0 with C++
--- Comment #11 from l dot lunak at suse dot cz 2009-04-29 13:21 --- (In reply to comment #10) > As a consequence, since NULL can not in an obvious way be a pointer, there is > no obvious warning that can be generated. Of course there is. NULL with gcc is not 0, 0L or (void*)0, it is __null. And gcc can make __null be whatever it wants, can it not? The same way it can warn about converting __null to integer. > The situation will be different with the upcoming C++1x standard where there > is null_ptr. Gcc already in practice has null_ptr. It's called __null. What would be the point of __null otherwise, to have a really sophisticated way to write 0? -- l dot lunak at suse dot cz changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|WONTFIX | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35669
[Bug c++/35669] NULL (__null) not considered different from 0 with C++
--- Comment #18 from l dot lunak at suse dot cz 2010-02-14 21:47 --- (In reply to comment #17) > Which one? We are not going to warn for conversions to boolean and we are not > going to warn for explicit conversions. I don't see anybody asking for that. > And we are not going to warn by default, only with -Wconversion. If you fail to see the difference between NULL being converted to integer being almost always a mistake and the flood of warnings caused by -Wcoversion to be almost almost harmless in real-world code, then you probably might as well not bother at all. A warning about something that's almost for sure a mistake being part of a flag that almost nobody uses is next to useless. > So, please post a testcase as minimal and self-contained (with the smallest > number of includes) as possible and point out > exactly what you expect to happen. Well, it's all in the original comment of this bugreport, but if you insist: Testcase (a.c): #include void foo( int a ); int main() { foo( NULL ); foo( 0 ); int a = NULL; return 0; } Expected output (like 'gcc -Wall -c a.c' provides): a.c: In function ‘main’: a.c:5: warning: passing argument 1 of ‘foo’ makes integer from pointer without a cast a.c:2: note: expected ‘int’ but argument is of type ‘void *’ a.c:7: warning: initialization makes integer from pointer without a cast a.c:7: warning: unused variable ‘a’ Actual output (what 'g++ -Wall -c a.c' provides): a.c: In function ‘int main()’: a.c:7: warning: unused variable ‘a’ The warning about the unused variable is obviously irrelevant. -- l dot lunak at suse dot cz changed: What|Removed |Added Status|WAITING |UNCONFIRMED http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35669
[Bug debug/41371] [4.5 Regression] var-tracking is slow and memory hungry
--- Comment #16 from l dot lunak at suse dot cz 2010-02-16 12:47 --- Created an attachment (id=19887) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=19887&action=view) testcase from kdesdk/umbrello If it helps, here's another testcase where 2G RAM is not enough. This is "g++ (SUSE Linux) 4.5.0 20100212 (experimental) [trunk revision 156733]" on x86_64 with -g -O2. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41371