Я понятия не имею, является ли это неопределенным (или какой-либо другой категорией несоответствия) согласно стандарту C, но я знаю, что если у вас есть две единицы перевода, которые не согласны с тем, тип 'foo' объявлен как 'класс' или 'структура', например:
ТУ 1
struct foo;
void f(foo&) { ... }
ТУ 2
class foo { ... };
void f(foo&);
void g()
{
foo x;
f(x);
}
тогда, по крайней мере, некоторые компиляторы (особенно MSVC ++) будут по-разному обрабатывать имя f
в каждой единице перевода, поэтому определение f
в TU 1 не удовлетворяет ссылке на f
в TU 2 и Вы получаете ошибку ссылки. Это происходит в реальной жизни, когда у вас есть заголовок A.h
, который определяет класс A
и должен ссылаться на классы B
, C
и D
, но достаточно их предварительного объявления (так что, вполне разумно, не включает B.h
и т. д.) - вам лучше использовать то же ключевое слово для тех предварительных объявлений, что и в реальных определениях!