5

Is there a way (compiler extensions are acceptable) to include C headers and mark included C functions as noexcept, but without modifying headers?

For example, I have a C library and its header header.h. No C++ callback will be passed into it so it never throws. Can I mark the included C functions as noexcept or tell compiler that they never throw, so that the compiler doesn't have to generate unused code and enable some possible optimizations for callers? Note that the C++ code using the C library should still be able to use exceptions (so disabling exceptions for the entire program is not an option).

extern "C" {
#include "header.h" // Is there a way to mark included C functions here as noexcept?
}
JaMiT
  • 14,422
  • 4
  • 15
  • 31
VainMan
  • 2,025
  • 8
  • 23
  • AFAIK most compilers don't even care about noexcept, and don't emit any special code. It is mostly for us, programmers. Am I wrong? – freakish Jan 14 '22 at 07:26
  • 4
    @freakish noxcept doesn't "emit" special code, but rather suppresses emission of code through optimisation. Allowing the compiler easily prove that no exception can be thrown is used by optimisers. – eerorika Jan 14 '22 at 07:28
  • Yeah, what I'm saying is that this actually doesn't happen. I mean, nothing is getting optimized with or without noexcept. At least not by default. Of course C++ does have some tools, e.g. move_if_noexcept, but this is a bit different story, doesn't happen automatically, you actually have to use it. Maybe this is why OP wants it. – freakish Jan 14 '22 at 07:31
  • 1
    @freakish It does happen. If my caller function is explicit noexcept, compiler will generate code, more or less, for exception handling. Edit: for example https://godbolt.org/z/Wc4bxq1M4 – VainMan Jan 14 '22 at 07:44
  • 1
    Should we assume that on the C++ side of things, you are using exceptions? (So a compiler flag to make all functions -- C and C++ -- effectively `noexcept` is not an option?) – JaMiT Jan 14 '22 at 07:45
  • 1
    Doesn't the compiler already know that `extern "C"` code will never throw? – JHBonarius Jan 14 '22 at 07:47
  • @JHBonarius it's UB to throw from extern "C" so it's the likely case. – alagner Jan 14 '22 at 07:52
  • 2
    @JHBonarius No. extern "C" only affects linkage name, eg. name mangling. You can write any C++ code in extern "C" block. – VainMan Jan 14 '22 at 07:53
  • 1
    @VainMan what about [this](https://stackoverflow.com/a/15845731/4885321)? – alagner Jan 14 '22 at 07:54
  • 1
    @alagner Do you have source for "it's UB"? – eerorika Jan 14 '22 at 07:59
  • 1
    @alagner Your link says what you should not do, not what you can not do. `extern "C"` can be language boundary but doesn't have to, compiler have to handle all possible valid cases. – VainMan Jan 14 '22 at 08:06
  • OK, I did a quick search in the standard, seems I misinterpreted what then answer I've linked previously then (or at least I cannot find anything proving I was right), mea culpa. – alagner Jan 14 '22 at 08:09
  • @JaMiT Yes. It's acceptable solution in some scenes, not mine at hand though. Thank you anyway. – VainMan Jan 14 '22 at 08:26
  • I think this is a very good candidate for a warning - I did investigate such a bug very recently - it is possible to detect it during the compilation of the unit which has the function definition. – mmomtchev Jan 14 '22 at 10:55
  • @VainMan *"It's acceptable solution in some scenes"* -- that's why I asked. Not because I believed that `-fno-exceptions` would solve your problem, but because it's a detail worth mentioning in the question (now added). This way, it will be easier for future visitors to recognize that a sometimes-acceptable approach is not being considered here. If one of them finds disabling all exceptions acceptable, they are now less likely to read this question and its answer(s) and conclude that their situation has no tidy solution. – JaMiT Jan 14 '22 at 21:37

1 Answers1

0

There isn't a way that you're looking for.

What you could do for example, is not use the header at all. Write your own header where the functions are marked noexcept. This of course has the drawback that you must maintain the new header and keep it up to date with changes in the library.

Or - if you can give up the premise of not modifying the header - you can add noexcept to the header while still keeping it compatible with C by wrapping the C++ features in macros. This is how for example C standard libraries are written, as they are inherited by C++ standard libraries.

eerorika
  • 232,697
  • 12
  • 197
  • 326