3

This is a two part question, the first regarding something written entirely in C++, the second part regarding the interaction between functions written in C but called from C++.

Part 1

Is it an ODR or other violation to have different translation units see different noexcept specifiers on the declaration for the same function? Specifically, if one unit sees:

void foo();

while another one sees:

void foo() noexcept;

Is it an ODR or other violation? You may assume that the function in reality never throws (i.e., it actually could be declared noexcept).

Part 2

Is it a violation if all C++ code sees the declaration as extern "C" void foo() noexcept;, but the function is actually defined (implemented) in C where the declaration (obviously) does not include the noexcept?

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • If it's defined in C, shouldn't you use `extern "C"` to declare it in C++? – Barmar Jan 13 '20 at 18:33
  • 2
    It's an ODR violation unless _"...each definition consists of the same sequence of tokens..."_ see: https://en.cppreference.com/w/cpp/language/definition – Richard Critten Jan 13 '20 at 18:34
  • "nction is actually defined (implemented) in C" -- C++ does not, as far as I know, define the semantics of C code that is linked to C++. As far as I know, all C code linked to C++ is unspecified how it works. Of course, in practice, it works. – Yakk - Adam Nevraumont Jan 13 '20 at 18:35
  • @Barmar - I do: see the first sentence in part 2. – BeeOnRope Jan 13 '20 at 18:37

1 Answers1

7

Is it an ODR ... violation?

It is not an ODR violation. These:

void foo();
void foo() noexcept;

are only declarations. They are not definitions and One Definition Rule does not restrict them.

is it an ... other violation?

Yes. It violates following rule (quote from latest satandard draft):

[except.spec]

If a declaration of a function does not have a noexcept-specifier, the declaration has a potentially throwing exception specification unless [exception that does not apply], in which cases the exception specification is as specified below and no other declaration for that function shall have a noexcept-specifier. ... A diagnostic is required only if the exception specifications are not the same within a single translation unit.


Is it a violation if all C++ code sees the declaration as extern "C" void foo() noexcept;, but the function is actually defined (implemented) in C where the declaration (obviously) does not include the noexcept?

Technically maybe. But C++ standard doesn't really apply to C, so this is probably under-specified. Even if the program is technically ill-formed, I'm not sure if there's any practical problem if one TU thinks that a function is noexcept as long as that function never throws.

For what it's worth, glibc declares standard C functions with throw() when using GCC only when included into C++.

Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326