Замена макросу вычисляющему длину массива
От: igna Россия  
Дата: 10.01.07 11:16
Оценка:
Чем заменить макрос вычисляющий длину массива?

#define LENGTH(a) (sizeof(a) / sizeof(*a))
Re: Замена макросу вычисляющему длину массива
От: _Dreamer Россия  
Дата: 10.01.07 11:24
Оценка: 6 (1)
Здравствуйте, igna, Вы писали:

I>Чем заменить макрос вычисляющий длину массива?


I>
I>#define LENGTH(a) (sizeof(a) / sizeof(*a))
I>


template <std::size_t N>
struct TypeWhichHasSizeExactly
{
    typedef char (&type)[N];
};

template <typename ArrayElementT, std::size_t N>
typename TypeWhichHasSizeExactly<N>::type arrayLengthHelper(ArrayElementT (&)[N]);

#define ARRAY_LENGTH(array) sizeof(arrayLengthHelper(array))

(с) взято здесь
Автор: Roman Odaisky
Дата: 01.11.06


их несколько вариантов было, поиск по ARRAY_LENGTH поможет.
Re[2]: Замена макросу вычисляющему длину массива
От: korzhik Россия  
Дата: 10.01.07 11:47
Оценка: +2
Здравствуйте, _Dreamer, Вы писали:

I>>
I>>#define LENGTH(a) (sizeof(a) / sizeof(*a))
I>>


_D>
_D>template <std::size_t N>
_D>struct TypeWhichHasSizeExactly
_D>{
_D>    typedef char (&type)[N];
_D>};

_D>template <typename ArrayElementT, std::size_t N>
_D>typename TypeWhichHasSizeExactly<N>::type arrayLengthHelper(ArrayElementT (&)[N]);

_D>#define ARRAY_LENGTH(array) sizeof(arrayLengthHelper(array))
_D>


что интересно: очень много всегда возни с этим макросом, много обсуждений и на rsdn и даже в boost.devel но вот я почему то никогда его не использовал, просто ни разу не был нужен
Может я один такой
Re[3]: Замена макросу вычисляющему длину массива
От: Lorenzo_LAMAS  
Дата: 10.01.07 11:58
Оценка:
А еще непонятно, зачем вообще возня. Я бы просто писал sizeof и т.п., без всяких левых сущностей.
Of course, the code must be complete enough to compile and link.
Re[4]: Замена макросу вычисляющему длину массива
От: korzhik Россия  
Дата: 10.01.07 11:59
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>А еще непонятно, зачем вообще возня. Я бы просто писал sizeof и т.п., без всяких левых сущностей.


ну говорят, чтобы указатель не передать вместо массива.
Re[2]: Замена макросу вычисляющему длину массива
От: korzhik Россия  
Дата: 10.01.07 12:02
Оценка: 1 (1) +1
Здравствуйте, _Dreamer, Вы писали:

_D>
_D>template <std::size_t N>
_D>struct TypeWhichHasSizeExactly
_D>{
_D>    typedef char (&type)[N];
_D>};

_D>template <typename ArrayElementT, std::size_t N>
_D>typename TypeWhichHasSizeExactly<N>::type arrayLengthHelper(ArrayElementT (&)[N]);

_D>#define ARRAY_LENGTH(array) sizeof(arrayLengthHelper(array))
_D>


если быть педантичным, то этот макрос имеет две маленькие проблемы:

1. не работает для локальных типов
void foo()
{
  struct baz {int x;};

  baz arr[10];

  ARRAY_LENGTH(arr);  
}


2. не работает для типов без имени
struct baz
{
struct {int x;} arr1[100]; 
};

int main()
{
   baz b;

  ARRAY_LENGTH(b.arr1);
}


но учитывая спорную практическую ценность этого подхода, то всё это фигня.
Re[3]: Замена макросу вычисляющему длину массива
От: Roman Odaisky Украина  
Дата: 10.01.07 12:18
Оценка:
Здравствуйте, korzhik, Вы писали:

K>что интересно: очень много всегда возни с этим макросом, много обсуждений и на rsdn и даже в boost.devel но вот я почему то никогда его не использовал, просто ни разу не был нужен

K>Может я один такой

Я использовал и много раз... Но то приходилось очень уж индусский код поддерживать... И вообще, boost::array рулит.

А за замечания спасибо. Интересно, можно ли внести такие исправления, чтобы макрос работал даже с локальными типами?
До последнего не верил в пирамиду Лебедева.
Re[4]: Замена макросу вычисляющему длину массива
От: korzhik Россия  
Дата: 10.01.07 12:32
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>А за замечания спасибо. Интересно, можно ли внести такие исправления, чтобы макрос работал даже с локальными типами?


да, врятли. Макрос основан на шаблонах, а шаблоны локальные типы не любят
Re[4]: Замена макросу вычисляющему длину массива
От: Warturtle  
Дата: 10.01.07 14:34
Оценка: 3 (1)
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, korzhik, Вы писали:


K>>что интересно: очень много всегда возни с этим макросом, много обсуждений и на rsdn и даже в boost.devel но вот я почему то никогда его не использовал, просто ни разу не был нужен

K>>Может я один такой

RO>Я использовал и много раз... Но то приходилось очень уж индусский код поддерживать... И вообще, boost::array рулит.


RO>А за замечания спасибо. Интересно, можно ли внести такие исправления, чтобы макрос работал даже с локальными типами?

Недавно кто-то писал, что в VC8, к примеру, локальные классы уже могут быть типовыми параметрами шаблона.
Re[4]: Замена макросу вычисляющему длину массива
От: _nn_  
Дата: 10.01.07 20:57
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, korzhik, Вы писали:


K>>что интересно: очень много всегда возни с этим макросом, много обсуждений и на rsdn и даже в boost.devel но вот я почему то никогда его не использовал, просто ни разу не был нужен

K>>Может я один такой

RO>Я использовал и много раз... Но то приходилось очень уж индусский код поддерживать... И вообще, boost::array рулит.


С помощью этого трюка
Автор: _Winnie
Дата: 19.11.05
(смотреть второе решение ниже) можно полностью обойтись boost::array во всех случаях.
И тогда никаких sizeof(x) / sizeof(x[0]) не надо писать.

RO>А за замечания спасибо. Интересно, можно ли внести такие исправления, чтобы макрос работал даже с локальными типами?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Замена макросу вычисляющему длину массива
От: Lorenzo_LAMAS  
Дата: 11.01.07 07:57
Оценка: 1 (1)
__>С помощью этого трюка
Автор: _Winnie
Дата: 19.11.05
(смотреть второе решение ниже) можно полностью обойтись boost::array во всех случаях.

__>И тогда никаких sizeof(x) / sizeof(x[0]) не надо писать.

Но как же эти макросы задолбали.
Of course, the code must be complete enough to compile and link.
Re[5]: Замена макросу вычисляющему длину массива
От: AndrewJD США  
Дата: 11.01.07 10:03
Оценка:
Здравствуйте, _nn_, Вы писали:

__>С помощью этого трюка
Автор: _Winnie
Дата: 19.11.05
(смотреть второе решение ниже) можно полностью обойтись boost::array во всех случаях.


ИМХО, уже лучше тогда писать sizeof(x) / sizeof(x[0]). Покрайней мере это гораздо легче читать.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re: Замена макросу вычисляющему длину массива
От: korzhik Россия  
Дата: 14.01.07 10:49
Оценка:
Здравствуйте, igna, Вы писали:

I>Чем заменить макрос вычисляющий длину массива?


I>
I>#define LENGTH(a) (sizeof(a) / sizeof(*a))
I>


Наверно многие уже знают, но я вот только наткнулся: VC2005 &mdash; _countof

У кого есть VC2005 посмотрите плиз как он реализован: в виде макроса или встроен в язык?
Re[2]: Замена макросу вычисляющему длину массива
От: rg45 СССР  
Дата: 14.01.07 11:01
Оценка: 10 (1)
"korzhik" <19450@users.rsdn.ru> wrote in message news:2300726@news.rsdn.ru...
> Здравствуйте, igna, Вы писали:
>
> I>Чем заменить макрос вычисляющий длину массива?
>
> I>
> I>#define LENGTH(a) (sizeof(a) / sizeof(*a))
> I>

>
> Наверно многие уже знают, но я вот только наткнулся: VC2005 &mdash; _countof
>
> У кого есть VC2005 посмотрите плиз как он реализован: в виде макроса или встроен в язык?

Макрос, определен так:
#if !defined(__cplusplus)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#else
extern "C++"
{
template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
#define _countof(_Array) sizeof(*__countof_helper(_Array))
}
#endif
Posted via RSDN NNTP Server 2.0
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: Замена макросу вычисляющему длину массива
От: korzhik Россия  
Дата: 14.01.07 11:04
Оценка:
Здравствуйте, rg45, Вы писали:

>> У кого есть VC2005 посмотрите плиз как он реализован: в виде макроса или встроен в язык?


R>Макрос, определен так:

R>
R>#if !defined(__cplusplus)
R>#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
R>#else
R>extern "C++"
R>{
R>template <typename _CountofType, size_t _SizeOfArray>
R>char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
R>#define _countof(_Array) sizeof(*__countof_helper(_Array))
R>}
R>#endif
R>


Спасибо. Вот в Microsoft шутники всё таки
Re[6]: Замена макросу вычисляющему длину массива
От: _nn_  
Дата: 15.01.07 19:33
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

__>>С помощью этого трюка
Автор: _Winnie
Дата: 19.11.05
(смотреть второе решение ниже) можно полностью обойтись boost::array во всех случаях.

__>>И тогда никаких sizeof(x) / sizeof(x[0]) не надо писать.

L_L>Но как же эти макросы задолбали.


Этот макрос нужен только когда нам размер неизвестен:
int a[] = {1,2,3,4,5};


Вариант первый это указать размер: boost::array<int, 5> a = {1,2,3,4,5};, другой вариант это макрос.

К счастью обычно размер известен, поэтому фокусы с макросами нам не обязательны.
Только boost::array
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Замена макросу вычисляющему длину массива
От: skeptik_  
Дата: 15.01.07 23:34
Оценка:
K>что интересно: очень много всегда возни с этим макросом, много обсуждений и на rsdn и даже в boost.devel но вот я почему то никогда его не использовал, просто ни разу не был нужен
K>Может я один такой
Тоже не понимаю, использую везде std::vector и никаких проблем.
Re[4]: Замена макросу вычисляющему длину массива
От: igna Россия  
Дата: 16.01.07 07:58
Оценка:
Здравствуйте, skeptik_, Вы писали:

_>Тоже не понимаю, использую везде std::vector и никаких проблем.


Иногда бывают полезны списки инициализации.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.