Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Статическая проверка диагностических утверждений, пример из книги Александреску 
V
    Опции темы
null56
Дата 23.8.2010, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Всем привет
Разбираюсь с книгой Александреску и пример, который приводит автор ни в какую не хочет собираться
Код

template<int> struct CompileTimeChecker
{
 CompileTimeChecker(...);
};

template<> struct CompileTimeChecker<false> {};

#define STATIC_CHECK(expr,msg) \
{ \
 class ERROR_##msg {};\
 (void)sizeof( CompilerTimeChecker<(expr)!=0>((ERROR_##msg())));\
}

template < class To, class From >
To safe_reinterpret_cast( From from )
{
 STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow );
 //return reinterpret_cast<To>(from);
 return To();
}

int main()
{
    void* somePointer = 0;
    char* c = safe_reinterpret_cast<char *>(somePointer);
    return 1;
}


Компилятор gcc
Вопрос:
1) почему не хочет собираться? это связано с компилятором или такие фокусы больше не проходят?
2) объясните пожалуйста, зачем автор применяет такой прием
Код

 (void)sizeof( CompilerTimeChecker<(expr)!=0>((ERROR_##msg())));\

на сколько я понял, всего лишь надо попытаться создать объект локального класса ERROR_##msg и передать его в конструктор класса CompilerTimeChecker, который влезет туда лишь при специализации с агрументом true. То есть нельзя ли было сделать  вот так (спрашиваю, потому что не собирается у меня пример)
Код

CompilerTimeChecker<(expr)!=0> temp(ERROR_##msg());\


 ЗЫ: я скачал свеженький вариант локи библиотеки, но там уже этот прием не используется, там всё просто
Код

#define LOKI_STATIC_CHECK(expr, msg) \
    { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; 


Заранее благодарен за помощь
PM MAIL   Вверх
baldina
Дата 23.8.2010, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



1. Хотелось бы увидеть ошибку компилятора. Хотя как минимум одна ошибка известна: нет определения шаблона struct CompilerTimeChecker 
есть CompileTimeChecker.
И круглые скобочки надо поставить вокруг вызова конструктора. Тогда компилятор перестанет думать что это функция, и sizeof станет корректным.
2. Можно и без и sizeof. Вариант с sizeof чуть более оптимизирован, т.к. не cоздается объекта в программе (вызов конструктора не приводит к созданию объекта, здесь только выражение для оператора sizeof, значение которого вычисляется в процессе компиляции)
3. Ну то же самое. В надежде, что умный компилятор оптимизирует не использующуюся переменную.
PM MAIL   Вверх
null56
Дата 23.8.2010, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Цитата(baldina @  23.8.2010,  09:29 Найти цитируемый пост)
1. Хотелось бы увидеть ошибку компилятора. Хотя как минимум одна ошибка известна: нет определения шаблона struct CompilerTimeChecker 
есть CompileTimeChecker.

Вот вывод
Цитата

In function ‘To safe_reinterpret_cast(From)’:
19: ошибка: нет декларации ‘CompilerTimeChecker’ в этой области видимости
In function ‘To safe_reinterpret_cast(From) [with To = char, From = void*]’:
31:   instantiated from here
19: ошибка: no match for ‘operator>’ in ‘0 > safe_reinterpret_cast(From) [with To = char, From = void*]::ERROR_Destination_Type_Too_Narrow()’

Но дело в том, что это происходит, с любым инстанцируемым типом...


Цитата(baldina @  23.8.2010,  09:29 Найти цитируемый пост)
И круглые скобочки надо поставить вокруг вызова конструктора. Тогда компилятор перестанет думать что это функция, и sizeof станет корректным.

укажите пожалуйста, мне кажется скобки уже стоят

Цитата(baldina @  23.8.2010,  09:29 Найти цитируемый пост)
Можно и без и sizeof. Вариант с sizeof чуть более оптимизирован, т.к. не cоздается объекта в программе (вызов конструктора не приводит к созданию объекта, здесь только выражение для оператора sizeof, значение которого вычисляется в процессе компиляции)

За это спасибо, теперь понятнее
PM MAIL   Вверх
azesmcar
Дата 23.8.2010, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



null56, 
смотри внимательно

Цитата(null56 @  23.8.2010,  10:16 Найти цитируемый пост)
CompilerTimeChecker

Цитата(null56 @  23.8.2010,  01:41 Найти цитируемый пост)
CompileTimeChecker


PM   Вверх
baldina
Дата 23.8.2010, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(null56 @  23.8.2010,  10:16 Найти цитируемый пост)
Цитата(baldina @  23.8.2010,  09:29 )
И круглые скобочки надо поставить вокруг вызова конструктора. Тогда компилятор перестанет думать что это функция, и sizeof станет корректным.

укажите пожалуйста, мне кажется скобки уже стоят


Код

struct foo {};

sizeof (foo ());  // error: foo() интерпретируется как вызов функции. функция не может быть аргументом sizeof
sizeof ((foo())); // ok: (foo()) интерпретируется как объект типа struct foo


тут

Это сообщение отредактировал(а) baldina - 23.8.2010, 14:03
PM MAIL   Вверх
baldina
Дата 23.8.2010, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



в С++ для разрешения неоднозначности все, что выглядит как функция, интерпретируется как функция.
в частности, 
Цитата

8.5
8. An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
[ Note: since () is not permitted by the syntax for initializer,
X a();
is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X.
The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). —end note ]

...на эти грабли, кажется, каждый наступает хотя бы раз...
PM MAIL   Вверх
null56
Дата 23.8.2010, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



azesmcar, да, это я проглядел спасибо

baldina, не знал, спасибо огромное, вот и я наступил на эти грабли
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0513 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.