Summary: | Add warning to detect noexcept functions that might throw [-Wnoexcept-mismatch] | ||
---|---|---|---|
Product: | gcc | Reporter: | Ryan Johnson <scovich> |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | UNCONFIRMED --- | ||
Severity: | enhancement | CC: | dcrocker, egallager, rafael, rdiezmail-gcc, webrown.cpp |
Priority: | P3 | Keywords: | diagnostic |
Version: | 4.9.0 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | ||
Bug Depends on: | |||
Bug Blocks: | 87403 |
Description
Ryan Johnson
2014-05-30 16:40:40 UTC
I too would find this very useful. However, it's essential that functions declared 'extern "C" ' are (or optionally can be) assumed to not throw exceptions. Otherwise, calls to C library functions and MCU vendor-supplied C header files from C++ functions declared 'noexcept' will trigger this warning. Also, the warning should be disabled when -fno-exceptions is used. extern "C" functions can throw, so it would be wrong to unconditionally assume they can't. (In reply to Jonathan Wakely from comment #2) > extern "C" functions can throw, so it would be wrong to unconditionally > assume they can't. True, you can write an extern "C" function that throws. But does it ever make sense to? I don't think so. Functions written in C and then declared extern "C" in a C++ program so that they can be called from C++ won't throw or propagate exceptions, even if they end up calling functions written in C++ that throw. The only reason to write a function in C++ and declare it extern "C" is so that it call be called from C, in which case it had better not throw. (In reply to David Crocker from comment #3) > (In reply to Jonathan Wakely from comment #2) > > extern "C" functions can throw, so it would be wrong to unconditionally > > assume they can't. > > True, you can write an extern "C" function that throws. But does it ever > make sense to? I don't think so. Functions written in C and then declared > extern "C" in a C++ program so that they can be called from C++ won't throw > or propagate exceptions, That's not true. std::bsearch and std::qsort are counterexamples. You don't know what the user-provided function does, and you can't assume it doesn't throw. > even if they end up calling functions written in > C++ that throw. The only reason to write a function in C++ and declare it > extern "C" is so that it call be called from C, in which case it had better > not throw. That's an incorrect assumption. Not all extern "C" functions are written in C++. Even if they are, you can't assume they don't throw because they could use callbacks that can throw, or they might throw even in C programs (which works fine for some targets, unwinding the stack exactly as a C++ program wants it to). It would be OK to optionally assume functions with C language linkage don't throw, but it must be optional. You seem to be assuming that C++ exceptions can propagate through functions compiled with a C compiler. On most platforms, they normally cannot, because a C compiler does not produce the information needed for the C++ unwind mechanism to unwind the call stack. If you want bsearch and qsort to propagate C++ exceptions, on most platforms the implementations of those functions would have to be compiled either using a C++ compiler, or with a C compiler using a special option that tells the compiler to include the tables and/or code needed to propagate C++ exceptions. Otherwise the exception will end up at std::unexpected. Maybe bsearch and qsort in newlib are compiled this way, I haven't checked. I don't care whether extern "C" functions are to be assumed noexcept by default or another compiler option is needed to specify that. But without this facility, the proposed warning will be useless in practice, at least for people like me writing embedded software. (In reply to David Crocker from comment #5) > You seem to be assuming that C++ exceptions can propagate through functions > compiled with a C compiler. I'm not assuming anything. I know for a fact that they can do so on some platforms. It is provably incorrect to say that extern "C" functions can't exit via an exception. So it would be wrong to add a new warning which unconditionally assumes extern "C" functions never throw. > On most platforms, they normally cannot, because Define most. GCC supports it by default on many platforms. > a C compiler does not produce the information needed for the C++ unwind > mechanism to unwind the call stack. If you want bsearch and qsort to > propagate C++ exceptions, on most platforms the implementations of those > functions would have to be compiled either using a C++ compiler, or with a C > compiler using a special option that tells the compiler to include the > tables and/or code needed to propagate C++ exceptions. Otherwise the > exception will end up at std::unexpected. Maybe bsearch and qsort in newlib > are compiled this way, I haven't checked. What has newlib got to do with anything? Are you asking for a new option that only works when using newlib? Don't assume your use case is universal. New GCC options need to consider a broad range of uses. > I don't care whether extern "C" functions are to be assumed noexcept by > default or another compiler option is needed to specify that. But without > this facility, the proposed warning will be useless in practice, at least > for people like me writing embedded software. OK, so why do you keep arguing about it? What I said is it that treating extern "C" functions as non-throwing needs to be optional. You've repeatedly argued that my reasoning for that is bogus, based on "does it ever make sense to?" and the answer is yes, sometimes it does. (In reply to Jonathan Wakely from comment #2) > extern "C" functions can throw, so it would be wrong to unconditionally > assume they can't. Yes that is correct. Even extern "C" functions could be written in C++ to provide an interface from C to C++ code. retitling to include proposed warning flag name in title |