Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ 15 ] 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

согласится со мной, что такое кардинальное изменение смысла объявления друга из-за опускания имени пространства имен, по меньшей мере, неожиданно. Таких конструкций следует избегать.

Причина 3: удивляет компиляторы

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

Испытаем коды, относящиеся к случаям I и 3, на разных компиляторах, и проанализируем результат. Воспринимают ли компиляторы стандарт так же, как и мы (дочитавшие книгу до этого места)? Будут ли, по крайней мере, самые мощные компиляторы вести себя так, как мы от них ожидаем? Оба ответа отрицательны...

Сначала обратимся к случаю 3.

пример 8-1 - еще раз

namespace boost {

tempiate<typename т> void checked delete( T* x ) { ... остальной код ... delete x;

class Test { -TestO { } изначальный код

friend void boost::checked deleteC Test* x );

i nt mainO {

boost::checked delete( new Test );

Попробуйте скомпилировать этот код на вашем компиляторе, и мы сравним наши результаты (см. табл. 8.1).

Таблица 8.1. Результат компиляции примера 8-1 разными компиляторами

Компилятор

Результат

Сообщение об ошибке

Borland 5.5

Comeau 4.3,0.1

Digital Mars 8.38

Error

Symbol Undefined ?checkcd.....dclete@@YAXPAV-

Test@@@Z (void cdecl checked.....dclctc(Tc5t *))

EDG 3,0.1

Intel 6.0.1

gcc 2.95.3

Error

~boost::checked delete(Test *) should have been declared inside boost

gcc .3.4

Error

void boost::checked delete(Test*) should have been declared inside boost

Metrowerks 8.2

Error

friend void boost::checked delete( Test* x ); name has not been declared in namespace/class

MS VC++ 6.0

Error

nonexistent function boost::checked deiete specified as friend

MS VC++ 7.0 (2002)



Компилятор

Результат

Сообщение об ошибке

MS VC++ 7.1 (2003)

Error

boost;:checked de!ete : not a function

MS VC++ 8.0 (2005) beta

Итак, наш тест показывает, что этот синтаксис плохо распознается современными компиляторами, один из них даже неоднократно меняет свое мнение по поводу данного кода в процессе разработки новых версий. Кстати, нас не должно удивлять, что компиляторы Comeau, EDO и Intel скомпилировали этот код, поскольку все они основаны на реализации EDO С++. Получается, что из пяти различных реализаций языка три (Digital Mars, gcc и Metrowerks) не понимают такой синтаксис, два других (Borland и EDO) понимают, и еще один никак не может определиться (Microsoft).

Теперь изменим исходный текст так, чтобы он относился к случаю 1.

пример 8-2: другой способ объявления друга

namespace boost {

tempiate<typename т> void checked de1ete( т* x ) { ... остальной код ... delete x;

class Test { -TestO { }

Альтернативный способ

friend void boost::checked de1ete<> ( Test* x );

int main О {

boost::checked delete( new Test );

Можно использовать и эквивалентную форму записи

friend void boost::checked delete<Test>( rest* x );

Результат исследований более оптимистичен - такой код понятен уже для большего количества компиляторов (см. табл. 8-2.).

Таблица 8.2. Результат компиляции примера 8-1 разными компиляторами

Компилятор

Результат

Сообщение об ошибке

Borland 5.5

Comeau 4.3.0.1

Digital Mars 8.38

EDG 3.0.1

Intel 6.0.1

gcc 2.95.3

Error

boost::checkcd dclete(Tesl *) should have been declared inside "boost

gcc 3.1.1

Error

void boost::checked de!ete(Test*) should have been declared inside boost

gcc 3.4

Error

void boost::chcckcd dcietc(Test*) should have been declared inside boost



Компилятор

Результат

Сообщение об ошибке

Metrowerks 8.2

MS VC++ 6.0

Error

nonexistent function boost::checked delete

specified as friend

MS VC++ 7.0 (2002)

MS VC++ 7.1 (2003)

MS VC++ 8.0 (2005) beta

Случай 1 выглядит более привлекательно и безопасно - он работает почти на всех современных компиляторах, кроме gcc.

Отступление: проблема в пространстве имен

Заметим, что если бы интересующий нас шаблон функции не находился в другом пространстве имен, то мы бы могли спокойно использовать случай 1 практически на всех современных компиляторах.

пример 8-3: checked delete не в пространстве имен Больше нет boost::

tempiate<typename т> void checked delete( T* x ) { 11 . . . прочий код ... delete x;

"boost:" больше не нужен class Test {

friend void checked delete<Test>( rest* x );

i nt mai n() {

checked delete( new Test );

Результаты исследования приведены в табл. 8.3. Таблица 8.3. Результат компиляции примера 8-3 разными компиляторами

Компилятор

Результат

Сообщение об ошибке

Borland 5.5

Comeau 4.3.0.1

Digital Mars 8.38

EDG 3.0.1

Intel 6.0.1

gcc 2.95.3

gcc 3.4

Metrowerks 8.2

MS VC++ 6.0

Error

syntax error (just cant handle it)



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ 15 ] 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85