Является ли нарушением ODR наличие противоречивых исключений в декларации? - PullRequest
3 голосов
/ 13 января 2020

Это вопрос из двух частей: первый касается чего-то написанного полностью на C ++, второй - взаимодействия между функциями, написанными на C, но вызванными из C ++.

Part 1

Это ODR или другое нарушение, когда разные единицы перевода видят разные noexcept спецификаторы в объявлении для одной и той же функции? В частности, если одна единица видит:

void foo();

, а другая видит:

void foo() noexcept;

Это ODR или другое нарушение? Вы можете предположить, что функция в действительности никогда не генерирует (т. Е. Фактически она может быть объявлена ​​noexcept).

Часть 2

Является ли это нарушением, если весь код C ++ видит объявление как extern "C" void foo() noexcept;, но функция фактически определена (реализована) в C, где объявление (очевидно) не включает noexcept?

1 Ответ

7 голосов
/ 13 января 2020

Это нарушение 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 ++.

...