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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблем с выводом результата функции 
:(
    Опции темы
vinter
Дата 14.1.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(UnrealMan @  14.1.2009,  14:33 Найти цитируемый пост)
то такая попытка влечёт undefined behavior.

на каком основании? Пожалуйста пункт из стандарта, да и логику рассуждений неплохо бы расписать. Как по твоему декремент указатель может быть UB?


--------------------
Мой блог
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



UnrealMan, ты невнимательно читал меня.
естественно для разных типов итераторов эффективный код будет разный. и не удивлюсь, если в конкретной реализации STL  он будет похож на то, что я написал для bidirectional и random access соответственно  smile
я как раз имел в виду, что для bidirectional (не random) нет эффективной реализации distance. я пока не вижу более эффективной реализации для этого вида итераторов, т.е. без двух сравнений в цикле.

не поленюсь после поста посмотреть в исходники STL...

Цитата

Если в функцию в качестве параметра end передаётся указатель на конец массива, одновременно являющийся его началом (такой массив может быть создан посредством new T[0]), а потом к end пытаются применить декремент, то такая попытка влечёт undefined behavior.


в чем undefined behavior? разадресовывать его бессмысленно, но изменение самого указателя - вполне осмысленная операция. причем гарантируется, что ++(--p) == p

Добавлено через 3 минуты и 2 секунды
посмотрел. вот результат:

STLPort
Код

template <class _BidirectionalIter>
_STLP_INLINE_LOOP void
__reverse(_BidirectionalIter __first, _BidirectionalIter __last, const bidirectional_iterator_tag &) {
  for (; __first != __last && __first != --__last; ++__first)
    iter_swap(__first,__last);
}


template <class _RandomAccessIter>
_STLP_INLINE_LOOP void
__reverse(_RandomAccessIter __first, _RandomAccessIter __last, const random_access_iterator_tag &) {
  for (; __first < __last; ++__first)
    iter_swap(__first, --__last);
}



VC++ 7.1
Код

template<class _BidIt> inline
    void _Reverse(_BidIt _First, _BidIt _Last, bidirectional_iterator_tag)
    {    // reverse elements in [_First, _Last), bidirectional iterators
    for (; _First != _Last && _First != --_Last; ++_First)
        std::iter_swap(_First, _Last);
    }

template<class _RanIt> inline
    void _Reverse(_RanIt _First, _RanIt _Last, random_access_iterator_tag)
    {    // reverse elements in [_First, _Last), random-access iterators
    for (; _First < _Last; ++_First)
        std::iter_swap(_First, --_Last);
    }


я не удивлен...

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


Опытный
**


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

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



Цитата(vinter @  14.1.2009,  14:15 Найти цитируемый пост)
на каком основании?

На таком, что это следует из текста стандарта.

Цитата(vinter @  14.1.2009,  14:15 Найти цитируемый пост)
Как по твоему декремент указатель может быть UB?

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

Цитата(vinter @  14.1.2009,  14:15 Найти цитируемый пост)
Пожалуйста пункт из стандарта

А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior smile Или тут только я должен всё основательно разжёвывать и доказывать правоту своих слов?

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


Эксперт
****


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

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



Цитата(mes @ 14.1.2009,  13:16)
Цитата(baldina @  14.1.2009,  11:45 Найти цитируемый пост)
для обычных указателей все гораздо проще
...     std::swap (*first++, *--last);

либо -- не там, либо один лишний swap smile (условие гораздо дешевле, даже просто для логики, чем swap)

mes, практические накладные расходы на один swap ничтожно малы. и его оптимизация имхо не оправдывает усложнения кода. а так все просто и понятно.
ЗЫ: лишний swap будет только для последовательностей с нечетным числом элементов
PM MAIL   Вверх
mes
Дата 14.1.2009, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Цитата(baldina @  14.1.2009,  14:18 Найти цитируемый пост)
практические накладные расходы на один swap ничтожно малы. и его оптимизация имхо не оправдывает усложнения кода. а так все просто и понятно.

я специально добавил уточнение :

Цитата(baldina @  14.1.2009,  14:18 Найти цитируемый пост)
условие гораздо дешевле, даже просто для логики, чем swap


имхо,  в данном случае это не оптимизация, а правильный набор условий.

Добавлено @ 15:25
Цитата(baldina @  14.1.2009,  14:18 Найти цитируемый пост)
ЗЫ: лишний swap будет только для последовательностей с нечетным числом элементов 

неважно, главное он вызывает напряг и заставляет подумать, а не будет ли последствий от этого smile

но в целом наверное это дело вкуса..  

Это сообщение отредактировал(а) mes - 14.1.2009, 15:26


--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 14.1.2009, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(baldina @  14.1.2009,  15:06 Найти цитируемый пост)
UnrealMan, ты невнимательно читал меня.

Цитата(baldina @  14.1.2009,  15:06 Найти цитируемый пост)
я как раз имел в виду, что для bidirectional (не random) 

Ткни пальцем, где конкретно там у тебя говорилось про итераторы, не являющиеся random access.

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 15:27
PM MAIL   Вверх
mes
Дата 14.1.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Цитата

При чём тут distance?

Это он к тому, что (грубо) для не-RandomAccess итераторов операция < (реализованная через distance) является "тяжелой".

Это сообщение отредактировал(а) mes - 14.1.2009, 15:30


--------------------
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior smile Или тут только я должен всё основательно разжёвывать и доказывать правоту своих слов?


да, UnrealMan, свою правоту нужно доказывать  smile
в нашем случае совершенно неважно, куда он будет указывать. важно лишь то, что он не перестает быть указателем с осмысленным значением, к нему можно применять инкремент, декремент, сравнивать с другими указателями. в этом смысле здесь вполне specific behavior.
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(baldina @  14.1.2009,  15:29 Найти цитируемый пост)
в нашем случае совершенно неважно, куда он будет указывать.

Сможешь подтвердить свои домыслы выдержками из стандарта C++?
PM MAIL   Вверх
baldina
Дата 14.1.2009, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

Код

template <typename BidirectIt>
void mirror (BidirectIt first, BidirectIt last)
{
  while (first != last && first != --last)
  {
     std::swap (*first, *last);
     ++first;
  }
}



Цитата

есть альтернативные предложения? хотелось бы увидеть...
пожалуйста, с учетом, что first и last это bidirectional iterator


я написал версию именно для bidirectional iterators. 
мне казалось template <typename BidirectIt> довольно однозначно говорит об этом. потом я сказал это открытым текстом.

Добавлено через 1 минуту и 2 секунды
Цитата

Сможешь подтвердить свои домыслы выдержками из стандарта C++? 

UnrealMan, Стандарту ничего неизвестно о нашем конкретном приложении  smile 
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(baldina @  14.1.2009,  15:59 Найти цитируемый пост)
я написал версию именно для bidirectional iterators. 
мне казалось template <typename BidirectIt> довольно однозначно говорит об этом. 

Вот так выглядит объявление std::reverse в стандарте:

Цитата(C++03 пункт 25.2.9 Reverse)
Код
template<class BidirectionalIterator>
  void reverse(BidirectionalIterator first, BidirectionalIterator last);

И что отсюда следует? Что она не годится для работы с итераторами произвольного доступа?
PM MAIL   Вверх
baldina
Дата 14.1.2009, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



она-то годится. а вот версия для произвольного доступа не годится для двунаправленных.
PM MAIL   Вверх
vinter
Дата 14.1.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(UnrealMan @  14.1.2009,  16:14 Найти цитируемый пост)
А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior

Цитата

The operand of prefix -- is modified by subtracting 1. The operand shall not be of type bool. The requirements on
the operand of prefix -- and the properties of its result are otherwise the same as those of prefix ++. [ Note: For postfix
increment and decrement, see 5.2.6. —end note ]

Цитата

The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to
a complete object type.

где тут хоть слово про UB?

Цитата(UnrealMan @  14.1.2009,  16:14 Найти цитируемый пост)
Возможно, есть специфические архитектуры, где декремент указателя может привести к переполнению

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

Цитата(UnrealMan @  14.1.2009,  16:14 Найти цитируемый пост)
при отладке программы под профилировщиком может быть выдано предупреждение, а выискивать среди "ненужных" сообщений профилировщика те, которые свидетельствуют о реальных багах, мало кто любит.

бесспорно, но это никакого отношения к языку не имеет. К тому же это из головы или реально были траблы такие с профайлерами? С чего бы ему ругатся? границы не нарушены, разыменовывания не происходит


--------------------
Мой блог
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



короче мы походу запутались. распутываю:
UnrealMan указал, что два сравнения в цикле неэффективно.
1. я сказал, что если это Bidirectional Iterator (а я именно его и имел в виду), то вряд ли этот код можно улучшить.
поглядев в STL можно увидеть, что там реализации для Bidirectional и для Random Access практически идентичны моим.

2. требования к Bidirectional Iterator слабее, чем к Random Access, поэтому версия для Bidirectional Iterator более общая, она может работать и с Bidirectional и с Random Access. но не наоборот.

3. нигде в коде не происходит разадресации недействительного указателя, потому рассуждения о UB не имеют смысла
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(baldina @  14.1.2009,  16:16 Найти цитируемый пост)
она-то годится.

Ну, значит, из одного такого объявления не очевидно, что функция предназначена для работы с двунаправленными итераторами, не являющимися итераторами произвольного доступа. Какие тогда ко мне претензии?

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 16:23
PM MAIL   Вверх
Страницы: (4) Все 1 2 [3] 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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