Язык программирования C++. Вводный курс



         

Сопоставление объявлений в разных файлах


Одна из проблем, вытекающих из возможности объявлять объект или функцию в разных файлах, – вероятность несоответствия объявлений или их расхождения в связи с модификацией программы. В С++ имеются средства, помогающие обнаружить такие различия.

Предположим, что в файле token.C

функция addToken()

определена как имеющая один параметр типа unsigned char. В файле lex.C, где эта функция вызывается, в ее определении указан параметр типа char.

// ---- в файле token.C ----

int addToken( unsigned char tok ) { /* ... */ }

// ---- в файле lex.C ----

extern int addToken( char );

Вызов addToken() в файле lex.C

вызывает ошибку во время связывания программы. Если бы такое связывание прошло успешно, можно представить дальнейшее развитие событий: скомпилированная программа была протестирована на рабочей станции Sun Sparc, а затем перенесена на IBM 390. Первый же запуск потерпел неудачу: даже самые простые тесты не проходили. Что случилось?

Вот часть объявлений набора лексем:

const unsigned char INLINE = 128;

const unsigned char VIRTUAL = 129;

Вызов addToken()

выглядит так:

curTok = INLINE;

// ...

addToken( curTok );

Тип char

реализован как знаковый в одном случае и как беззнаковый в другом. Неверное объявление addToken()

приводит к переполнению на той машине, где тип char

является знаковым, всякий раз, когда используется лексема со значением больше 127. Если бы такой программный код компилировался и связывался без ошибки, во время выполнения могли обнаружиться серьезные последствия.

В С++ информация о количестве и типах параметров функций помещается в имя функции – это называется безопасным связыванием (type-safe linkage). Оно помогает обнаружить расхождения в объявлениях функций в разных файлах. Поскольку типы параметров unsigned char и char

различны, в соответствии с принципом безопасного связывания функция addToken(), объявленная в файле lex.C, будет считаться неизвестной. Согласно стандарту определение в файле token.C

задает другую функцию.




Содержание  Назад  Вперед