Страницы

Поиск по вопросам

понедельник, 9 декабря 2019 г.

Определение 2-х одинаковых классов не даёт ошибки

#cpp #language_lawyer


//Файл A.cpp
class A
{
public:
    int func( int i )
    {
        return i*i;
    }
};

//Файл Test.cpp
#include 
using namespace std;

class A
{
public:
    int func( int i )
    {
        return i*i*i;
    }
};

int main()
{
    A a;
    cout<
using namespace std;

int func( int i )
{
    return i*i*i;
}


int main()
{
    cout<


Ответы

Ответ 1



Согласно стандарту языка (правилу ODR) классы с external linkage (внешним связыванием), определенные в нескольких единицах трансляции, должны быть определены одинаково во всех этих единицах трансляции. Но диагностики этого не требуется. Точно так же, по ODR, inline-функции с external linkage, определенные в нескольких единицах трансляции, должны быть определены одинаково во всех этих единицах трансляции. Но диагностики этого не требуется. В вашем исходном примере наличествуют как раз две таких сущности - класс с external linkage и inline-функция с external linkage. Т.е. спецификация языка требует, чтобы эти сущности были определены одинаково во всех единицах трансляции, но следить за этой одинаковостью - в общем случае ваша задача. Продвинутый компилятор может помочь вам ловить такие ошибки, но это просто вопрос качества реализации. Как только ваша функция перестала быть inline, диагностика для нарушений ODR для такой функции сразу же формально потребовалась и компилятор ее успешно вам предоставил.

Ответ 2



В стандарте не уточняется, должен ли компилятор выдавать диагностическое сообщение, если нарушено правило одного определения. Он только говорит, что в этом случае поведение программы неопределенное (Раздел Стандарта "3.2 One definition rule", параграф 6). ...If the definitions of D do not satisfy these requirements, then the behavior is undefined. Иногда в нем явно указывается, что компилятор не обязан выдавать диагностическое сообщение, как в этой фразе (там же, параграф 4) 4...Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. Даже для того случая, когда вы определили в модуле A функцию вне класса без спецификатора функции inline, а в другом модуле она была определена внутри класса, а потому по умолчанию считается inline-функцией, и ваш компилятор (или линкер) выдал сообщение об ошибке, то даже в этом случае на самом деле компиляторы не обязаны выдавать диагностическое сообщение (Раздел "7.1.2 Function specifiers"): 4...If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. Это практически невозможно диагностировать компилятору. Вы должны довольствоваться неопределенным поведением программы.:)

Ответ 3



Test.cpp не знает о существовании A.cpp. Поэтому, используется класс из Test.cpp, в котором число возводится в куб. Если код из этих двух файлов переписать в один, то ошибка появится.

Комментариев нет:

Отправить комментарий