Это нарушение ODR ...?
Это не нарушение ODR. Эти:
void foo();
void foo() noexcept;
являются только декларациями. Они не являются определениями, и одно правило определения не ограничивает их.
это ... другое нарушение?
Да. Это нарушает следующее правило (цитата из последнего сатандардного черновика):
[исключением. Spec]
Если объявление функции не имеет спецификатора noexcept, объявление имеет потенциально выбрасывает спецификацию исключений, если [исключение, которое не применяется] , в этом случае спецификация исключений такая, как указано ниже, и никакое другое объявление для этой функции не должно иметь спецификатора noexcept-. ... Диагностика c требуется только в том случае, если спецификации исключений не совпадают в пределах одной единицы перевода.
Является ли это нарушением, если весь код C ++ видит объявление как extern "C" void foo () noexcept ;, но функция фактически определена (реализована) в C, где объявление (очевидно) не включает noexcept?
Технически может быть. Но стандарт C ++ на самом деле не относится к C, так что это, вероятно, недостаточно. Даже если программа технически плохо сформирована, я не уверен, есть ли какая-либо практическая проблема, если один TU считает, что функция noexcept
, пока эта функция никогда не выдает.
Для чего она стоит, glib c объявляет стандартные C функции с throw()
при использовании G CC только при включении в C ++.