Нет ошибки компилятора / компоновщика для однотипных классов, объявленных в разных исходных файлах

У меня есть 2 файла, как показано ниже, которые объявляют одно и то же имя class C:

// C1.cpp
class C {
public: void foo (int, float);
};

int main () {
C c;
c.foo(1, 2.3);
}

void C::foo (int, float) {}

// C2.cpp
class C {
public:
int i;  // <--- extra variable
void foo (int, float);  // <--- non static
};

void foo () {
C c;
c.foo(0, 0.0);
c.i = 0;
}

Компилируется нормально с g++ C1.cpp C2.cpp!

  1. Почему нет ошибки компилятора / компоновщика, когда совпадают только имена
    но тела не?
  2. Почему единственное определение C::foo(..) служит как для
    static а нестатические версии?
  3. Или если это просто еще один неопределенное поведение случай из компилятора,
    мы можем предотвратить это?

2

Решение

Ваша программа нарушает Одно определение правила и имеет неопределенное поведение. От n3337 3.2/5Акцент мой:

Может быть более одного определения типа класса (Раздел 9), тип перечисления (7.2), встроенная функция с
внешняя связь (7.1.2), шаблон класса (пункт 14), шаблон нестатической функции (14.5.6), член статических данных
шаблона класса (14.5.1.3), функция-член шаблона класса (14.5.1.1) или специализация шаблона для
какие параметры шаблона не указаны (14.7, 14.5.5) в программе при условии, что каждое определение
появляется в другом блоке перевода
, и при условии, что определения удовлетворяют следующим требованиям. Дано
такая сущность с именем D определена более чем в одной единице перевода, тогда

каждое определение D должно состоять из одной и той же последовательности токенов; а также

в каждом определении D соответствующие имена смотрели в соответствии с
3.4, относится к объекту, определенному в определении D, или
должен ссылаться на один и тот же объект после разрешения перегрузки
(13.3) и
после сопоставления частичной специализации шаблона (14.8.3), кроме
что имя может ссылаться на объект const с внутренней или без связи, если
объект имеет одинаковый литеральный тип во всех определениях D, а
объект инициализируется постоянным выражением (5.19) и значением
(но не адрес) объекта используется, и объект имеет
одинаковое значение во всех определениях D; а также

[… пропущенный материал, который не имеет прямого отношения к примеру …]

Если определения D удовлетворяют всем этим требованиям,
тогда программа должна вести себя так, как если бы было одно определение D. Если определения D не удовлетворяют
эти требования, то поведение не определено.

Вы не можете получить ошибку компилятора, потому что он «видит» только одну единицу перевода за раз. Компоновщик и его сообщения об ошибках выходят за рамки стандарта C ++, поэтому я считаю, что не может быть де юре ответьте, почему это не диагностирует. Я думаю, что это займет первое C символ, который встречает и отбрасывает остальное.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]