Александреску, (void)sizeof
От: Аноним  
Дата: 14.10.04 09:33
Оценка:
Начал читать Александреску, и там есть приблизительно такая конструкция (только названия изменены):

Class A;
(void) sizeof((          Checker<true>( A() )     ));



1. пришлось добавить скобки в sizeof(). иначе ошибка "cast to function type is illegal". Не подскажите что это значит.
2. какой смысл приведения к void.
Спасибо.
Re: Александреску, (void)sizeof
От: Аноним  
Дата: 14.10.04 09:36
Оценка:
ошибся, должно быть:

class A{};
(void) sizeof((          Checker<true>( A() )     ));
Re[2]: Александреску, (void)sizeof
От: Аноним  
Дата: 14.10.04 09:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>ошибся, должно быть:


А>
А>class A{};
А>(void) sizeof((          Checker<true>( A() )     ));
А>


Поменьшк всяких извращенцев типа Александреску читай и всё будет хорошо
Re: Александреску, (void)sizeof
От: Lorenzo_LAMAS  
Дата: 14.10.04 10:05
Оценка: 21 (2)
Как мне однажды объяснил jazzer, это приведение к (void) наверное, чтоб избежать ворнинга о бессысленном с точки зрения компилятора выражении.

void fun()
{
   1 + 2;
}


"ComeauTest.c", line 3: warning: expression has no effect
1 + 2;
^


void fun()
{
    (void)(1 + 2);
}

нету ворнингов
Of course, the code must be complete enough to compile and link.
Re: Александреску, (void)sizeof
От: Кодт Россия  
Дата: 14.10.04 10:26
Оценка: 28 (6)
Здравствуйте, Аноним, Вы писали:

А>1. Не подскажите что это значит.

А>2. какой смысл приведения к void.

Это разновидность static assert'а (конструкция, которая пытается скомпилироваться, но нигде не применяется).

Оператор sizeof(), в отличие от других, не требует вычисления операнда — только интересуется его типом.
Это позволяет, в частности, использовать его для дискриминации типов.
typedef char false_type;
typedef struct { char t[100]; } true_type;

template<class T, class U> struct is_convertible
{
  // нигде не определены, только объявлены
  true_type  discriminator(U u);
  false_type discriminator(...);
  static T& t;

  enum { value = sizeof(true_type) == sizeof(discriminator(t)) }
};


В разных контекстах приходится использовать разные static-assert'ы.
* шаблоны классов
* размеры массивов
* сигнатуры функций

(void)(expression) ингибирует любое применение этого выражения, кроме как в инструкции:
template<bool V> struct Asserter
{
  typedef int type;
};
template<> struct Asserter<false>
{
  // идентификатор type не объявлен
};

#define STATIC_ASSERT_EXPR(expr) \
    (void)( sizeof( typename Asserter<(expr)>::type ) )
//  |       |                         |        +-- предмет облома для компилятора
//  |       |                         +-- выражение, от которого зависит успех/облом
//  |       +-- просто взять тип; никаких действий в рантайме!
//  +-- избавляемся от неуместного применения этого макроса

...
main()
{
  STATIC_ASSERT_EXPR(true); // ок
  STATIC_ASSERT_EXPR(false); // ошибка: неизвестный тип Asserter<false>::type

  printf("%d", STATIC_ASSERT_EXPR(true)); // ошибка использования: rvalue типа void

У Александреску, похоже, предметом облома выступило существование публичного конструктора без параметров, то есть
template<bool V> struct Checker { Checker(){} };
template<> struct Checker<false> { private: Checker() {} };
Перекуём баги на фичи!
Re[2]: Александреску, (void)sizeof
От: jazzer Россия Skype: enerjazzer
Дата: 14.10.04 11:10
Оценка: 8 (1) :))) :)))
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Как мне однажды объяснил jazzer


а ведь я уже и сам не помню :)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Александреску, (void)sizeof
От: Lorenzo_LAMAS  
Дата: 14.10.04 11:54
Оценка: :))
J>а ведь я уже и сам не помню

Давно это было, я еще вроде как под Анонимом зашел
Of course, the code must be complete enough to compile and link.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.