Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: А почему так инициализация
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
DASM
Цитата(Forger @ Jul 26 2018, 19:18) *
Раз пошла такая пьянка, то договаривайте ))

да нечитаемо все стало, и реально слишком сложно для изучения. К тому же сегодня словил странный глюк в МS на range based loop, как дома проверю - напишу.
Forger
Цитата(DASM @ Jul 26 2018, 19:43) *
да нечитаемо все стало, и реально слишком сложно для изучения.

Странно ... wacko.gif По мне как раз все наоборот - более свежие стандарты плюсов позволяют наоборот - сделать код проще, меньше текста, лучше читаемость и лучше оптимизация компилятора.
Может M$ идет каким-то своим путем? ..
XVR
Цитата(Forger @ Jul 26 2018, 18:35) *
У меня лично вопрос остался один: какая часть этой слишком длинной литеральной строки будет обрезана в зависимости от BE/LE - правая или левая?
Старшая. Сначала литеральная константа преобразуется в int (с учетом BE/LE), затем этот int будет усечён (если понадобится) по обычному правилу приведения типов.

Стандарт на этот счет весьма неопределен - implementation dependent
DASM
Цитата(Forger @ Jul 26 2018, 19:18) *
Раз пошла такая пьянка, то договаривайте ))

вот что тут https://msdn.microsoft.com/ru-ru/library/zzw4bwhd.aspx Микрософт имел в виду в
Код
vector <int> v5(5);
    for (auto i : v5) {
        v5[i] = i;
    }

и пишут, что v5 = 0 1 2 3 4 . А он нулевой будет в итоге, i это значения ветора по копии, а никак не индекс
Forger
По логике i тут должен быть int, для этого тут поставлен auto.
Такая конструкция должна правильно работать уже с C++11. Или я что-то не понимаю?
DASM
Цитата(Forger @ Jul 27 2018, 08:25) *
По логике i тут должен быть int, для этого тут поставлен auto.
Такая конструкция должна правильно работать уже с C++11. Или я что-то не понимаю?

v5[i] = i; - это фигня полная. Выражение for (auto i : v5) пробежит по всему вектору, присваивая i последовательные значения из этого вектора. Это не индекс. Так как вектор создан нулевым, то это будет так :
v5[0] = 0;
v5[0] = 0;
v5[0] = 0;
v5[0] = 0;
v5[0] = 0;
5 раз
Если сделать
Код
    vector <int> v5(5, 10);
    for (auto i : v5) {
        v5[i] = i;
    }

то будет access violation
ибо это v5[10] = 10; 5 раз подряд
Arlleex
Цитата(DASM @ Jul 27 2018, 09:42) *
то будет access violation

Именно из-за вот таких приколов и сложностей в понимании лично я не взлюбил C++. Хотя и достаточно вумных книжек прочитал по нему... Со временем понял, что выражение "Веревка достаточной длины, чтобы выстрелить себе в ногу(с)" имеет смысл. Был у нас один сотрудник, который всегда писал программы с применением, возможно, всех фишек C++. В итоге я ничего не понял из листинга (совсем!) даже относительно несложного проекта, а при попытке объяснить код сам программист пришел в замешательство со словами "ну, так делают другие программисты и оно так проще для понимания и удобнее". Жесть. И вот лично я люблю Си, чистый Си. И, возможно, не прочь выучить C++ нормально - но куда угнаться-то? Постоянно что-то новое. Считаю, что язык должен быть строгим в своем синтаксисе и однозначно трактуемым. Бомбануло у меня, помню, тогда, когда нашел штук пять разных способов инициализации членов класса при объявлении объекта... Брр, даже не стану вспоминать. Можете ругать biggrin.gif
Forger
Цитата(DASM @ Jul 27 2018, 08:42) *
Это не индекс.

По-ходу i - это в данном случае итератор ...

Попытался эти примеры прокомпилить в старом добром keil (компилятор v6).
Примеры собирает, но отлаживать их вообще неудобно: вроде i по окну watch - int, а нифига - это действительно итератор. Пример и правда не работает, как ожидается ((



Честно говоря, не использовал так активно штатные шаблоны (в частности std::vector). До умного for() так и не добрался.
Выяснил, что они могут неявно использовать кучу.
А кучу не использую, в известных целях (речь про обычные МК).

В свое время как-то делал самописный iterator, for_each, умный указатель ... минимально необходимые. Недавно добрался до чудесной штуки - делегаты...
В основном - в академических целях, но потом "проникся" )) Тогда использовал "старые" плюсы.
Но в новых стандартах плюсов они уже есть и готовые (кроме делегатов), но, в очередной раз прихожу к выводу, что они адски "толстые", по крайней мере в применении к обычным МК.

Мне лично из C++11 (для меня нового) пришлись по душе жесткие ограничения при неявном приведении типов - нужно ставить явный static_cast или переписывать код.
Также пригодилась инициализация полей классов прямо в описании класса (например, какие-нить константы), т. е. максимально возможный уход от #define.
const_expr - вообще чудесная штука. Также считаю полезными final и override.... Это пока то, что вспомнил с ходу.

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

DASM
i это не итератор, это локальная переменная типа элемента вектора. Сравните
Код
    struct fio
    {
        string f;
        string i;
    };
    vector <fio> names {{ "ivan", "ivanov" }, {"petr", "petrov"}};
    for (auto &r : names)    
        r.i = "sidorov";
    for (auto r : names)
        cout << r.f << " " <<  r.i << endl;
Herz
Господа, пора бы остановиться, а? Очень не хочется превращения темы в очередной холивар.
Понятно, что у любых языков, стандартов и компиляторов полно недостатков. Тем более понятно, что умельцы всегда могут наворотить чудес в коде...
Обсуждать всякие причуды, валя всё в кучу, смысла нет, ИМХО.
Цитата(Arlleex @ Jul 27 2018, 09:26) *
Можете ругать biggrin.gif

Нет, давайте не будем. У всех свои предпочтения, но провоцировать свару не надо. Это предупреждение.
Forger
Цитата(DASM @ Jul 27 2018, 10:29) *
i это не итератор, это локальная переменная типа элемента вектора.

В моем компиляторе - это не просто int. Я это проверил: попытка присвоить содержимое этого i кому-нить еще (я пробовал простой массив int a[5]; ), приводит к копирования некого адреса где-то в ОЗУ, но вовсе не содержимого. Это видно в окне watch.
Да и ходьба по шагам, где происходит обращение к i, кидает во внутренний некий файл iterator, где все это происходит.
Короче, for() в этом компиляторе тут ни разу не for() как это в привычном C или старом C++03, а разворачивается в конструкцию по-сложнее: https://en.cppreference.com/w/cpp/language/range-for (см. раздел Explanation)
По крайней мере, если речь идет про vector или что-то подобное.
DASM
Это int. Дома посмотрю, почему у Вас сомнения
DASM
Проверил, это точно int , собственно и сомнений не было. Итераторы конечно используются для такого for, но тип i - это int
Код
    vector <int> iv (5, 1);
    for (auto i : iv)
    {
        int tmp;
        decltype (i) intger = 0;
        tmp = intger;
        intger = tmp;        
    }

Forger
Цитата(DASM @ Jul 29 2018, 15:15) *
Проверил, это точно int , собственно и сомнений не было. Итераторы конечно используются для такого for, но тип i - это int

Попробуйте это i присваивать внутри цикла например в какой нить примитивный массив из int, но для индексации внутри массива НЕ используйте саму i.
Что будет в массиве при выходе из цикла?
DASM
Цитата(Forger @ Jul 29 2018, 16:11) *
Попробуйте это i присваивать внутри цикла например в какой нить примитивный массив из int, но для индексации внутри массива НЕ используйте саму i.
Что будет в массиве при выходе из цикла?

Код
    vector <int> iv (5, 1);
    int trace[5];
    int ix = 0;
    for (auto i : iv)
    {
        trace[ix++] = i;
    }

trace стал 1,1,1,1,1 что абсолютно верно
Forger
Заглумил я тут всех sm.gif
Короче, увеличил кучу, все стало работать правильно! Дело было в том, что куча у меня не используется и на нее выделяется от силы 16 байт. Тут этого было мало.

Ради финальной проверки, инициализирую iv так:
Код
vector <int> iv = {1, 2, 3, 4, 5};
int trace[5];
int ix = 0;
for (auto i : iv)
{
    trace[ix++] = i;
}


И результат соответствующий: trace: 1, 2, 3, 4, 5.

Получается, что все верно: при каждой итерации for (auto i : iv) вызывается оператор копирования из вектора iv, а результат кладется в i, которая все верно - обычная int (проверил через sizeof)
Имхо, это несколько непривычно для восприятия цикла for, ведь "i" тут - вовсе не индекс для перебора внутри вектора, а лишь копия одного из его элементов,
или по-другому - результат, возвращаемый внутренним итератором (в данном цикле создается неявно).

Фактический такой пример будет работать правильно, если iv заранее правильно заполнить:
Код
vector <int> iv = {0, 1, 2, 3, 4};
int trace[5];

for (auto i : iv)
{
    trace[i] = iv[i];
}

Тогда trace: 0, 1, 2, 3, 4

sm.gif


Кстати, с полностью включенной оптимизацией это все выходит довольно компактно и работает шустро (судя по данным из окна disasm)!

зы. Удивило, что даже статическое (или в стеке) создание "банального" vector все равно требует наличия кучи sad.gif
Это как-то странно. Надо бы разобраться....
DASM
"несколько непривычно для восприятия цикла for," зато удобно, например скалярное умножение вектора на 2 :
Код
for (auto& i : iv)
  i *= 2;

хотя в принципе можно и через разыменование итератора.. в общем как сделано так сделано
"если iv заранее правильно заполнить:" мне непонятно как в микрософт попал пример с такой жуткой ошибкой
" vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то?
Forger
Цитата(DASM @ Jul 29 2018, 19:44) *
мне непонятно как в микрософт попал пример с такой жуткой ошибкой
Значит, ошибок там может быть еще больше ...

Цитата
" vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то?

Это логично при изменении размера вектора (добавляем/удаляем), но ведь не для создания же ... Это-то меня и удивляет wacko.gif
DASM
ничего не понял. Предлагаете делать вектор на стеке, а если понадобится изменить его - быстро перекидывать в кучу?
Forger
Цитата(DASM @ Jul 29 2018, 20:08) *
ничего не понял. Предлагаете делать вектор на стеке, а если понадобится изменить его - быстро перекидывать в кучу?

Я про то, где хранится описательная часть вектора. Т.е. некая структура, хранящая, скажем, двусвязный список и другую служебную инфу по вектору.
Короче, логика работы понятна: вектор состоит из двух "кусков": описательная часть вектора, лежит там, где создаем (стек, статика или даже куча).
А сами данные - всегда в куче.
По логике, получается, если вектор пустой, то и нет обращения к куче.
Но даже статическое создание вектора с известным числом элементов все равно использует кучу... Разобрался ))

Гы, лезем в дебри std, а это уже откровенный офф sm.gif
esaulenka
Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ?

"Откровенный офф" - это пара страниц обсуждения дурацкой опечатки у майкрософта.

А STL прямо вот очень рекомендую посмотреть. Умные люди понаделали велосипедов почти на все случаи жизни.

PS для статического создания массивов есть std::array, ему куча не нужна (но при этом у него нет push()/pop())
PPS в кишках std::vector НЕТУ двусвязного списка (и вообще списка нет). Это один сплошной массив. И да, этот массив создеётся в куче.
Forger
Цитата(esaulenka @ Aug 3 2018, 19:20) *
Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ?

Эта тема вообще ни разу не про C++ и уж тем более про STL wink.gif
Но тенденция "скатиться к этому" есть почему-то у каждой темы в этом разделе ...

Цитата
"Откровенный офф" - это пара страниц обсуждения дурацкой опечатки у майкрософта.

Это не офф, это - пустой треп cool.gif

Цитата
А STL прямо вот очень рекомендую посмотреть. Умные люди понаделали велосипедов почти на все случаи жизни.

К сожалению, STL довольно толстая библиотека и, если и стоит ее использовать в конкретнтных встраиваемых приложениях, то как можно активнее.
Поэтому пока что у меня лично нет возможности совать ее во все проекты без исключения.
Другая причина - активное использование кучи.
Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет),
а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись.
А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню).
Например, вместо фрагментируемой кучи использовать более безопасные "пулы" для конкретно взятых классов.
С этой точки зрения Ваша фраза "понаделали велосипедов" может звучать уже иначе wink.gif

Цитата
PS для статического создания массивов есть std::array, ему куча не нужна (но при этом у него нет push()/pop())

Это все понятно ))) Книжки читать умеем )
Но речь зашла именно про vector и почему у меня он так работал. Но к счастью разобрался. Короче, проехали laughing.gif

Цитата
PPS в кишках std::vector НЕТУ двусвязного списка (и вообще списка нет). Это один сплошной массив. И да, этот массив создеётся в куче.

Некая "описательная" часть этого массива все равно требует места для хранения, а точнее хранится именно там в какой области объявили этот vector.
Например, для случая: std::vector <int> v = {0, 1, 2, 3, 4};
sizeof(v) = 12 байт (arm compiler v6)

А уже сами данные вектора хранятся в куче.
Именно это момент вызвал проблемы в моем случае.
Кстати, размер выделенных в куче данных может оказаться даже больше, чем было "запрошено". Таков функционал этого vector - выделяет с неким запасом.

Напомню причину: у меня в текущих и старых проектах куча имеет минимально возможный размер (вроде 8 байт) и в принципе не используется, т.к. не особо-то и нужна.
По-хорошему мне стоит "перегрузить" штатные malloc и free (их используют new/delete) на некие "заглушки-ловушки"...
XVR
Цитата(Forger @ Aug 3 2018, 19:47) *
Другая причина - активное использование кучи.
Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет),
а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись.
А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню).
Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор (и он практически никогда не передаётся, а используется аллокатор по умолчанию - через new/delete и кучу)
Делаете свой аллокатор (с любым местом расположения объектов и алгоритмом алокации) у вуаля - всё управление кучей в ваших руках sm.gif

Forger
Цитата(XVR @ Aug 4 2018, 19:38) *
Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор

Тем проще ))
Тем не менее, проблем с неявным обращением к куче, т.е. вызовом этого самого аллокатора, увы, все равно не избежать
Фактически, при активном использовании STL, имхо, всегда нужно держать "руку на пульсе": строчить свои аллокаторы на каждый вид объектов...
Повторюсь, что речь в данном случае про встраиваемые системы на обычным МК.
Пока что очкую применять STL в аппаратно-критичных приложениях, а других у меня и нету ))
Kabdim
Не стоит забывать что stl который с компилятором не прибит гвоздями. В геймдеве схожие с эмбедедом проблемы и написаны адаптированные под такие проблемы библиотеки. EASTL например, который выглядит намного разумней того что предлагает стандарт и производители компиляторов.
Forger
Цитата(Kabdim @ Aug 5 2018, 13:05) *
EASTL

EASTL как вариант, конечно, хорошо. К тому же он полный опенсорс с необходимыми бенчмарками и соотв. тестами, но есть одно важное НО:
применение STL, судя по всему, требует соотв. экспиренса в наших программных делах. И, судя по всему, весьма немалого!
Тут многие местные "программеры" от банальных плюсов шарахаются, как от вампиры от чеснока, а что уж говорить про STL....
Признаюсь, и я не исключение: например, категорически не применяю heap wacko.gif

А у ж в этом разделе "В помощь начинающему > Программирование" весь этот STL - это как показать самолет изолированному племени аборигенов cranky.gif
Имхо, "демонстрация" STL в реальных проектах зачастую может выглядеть как банальное хвастовство перед коллегами по проекту, а вовсе не по необходимости wink.gif
Провожу аналогию с "голым" С и плюсами - дай плюсы, например, упоротому фанату-указателей-где-надо-и-не-надо, так он и код на плюсах умудрится сделать опасным и напрочь нечитаемым и вообще не поддающимся сопровождению angry.gif
Поэтому я, уверен, что при должном и разумном применении этот самый STL даже в "стоковом" виде имеет место быть, как раз именно по необходимости.
Herz
Цитата(Forger @ Aug 5 2018, 18:20) *
применение STL, судя по всему, требует соотв. экспиренса в наших программных делах.

А простого опыта будет недостаточно? Может, в этом собака порылась? Люди опасаются, что с "экспириенсом" у них проблемы, а оно и... "не так страшен черт", если разобраться...
Forger
Цитата(Herz @ Aug 5 2018, 21:53) *
А простого опыта будет не достаточно?
Увы, этого не достаточно ((
Нужно читать очень много чужого кода, очень много.


Цитата
Люди опасаются, что с "экспириенсом" у них проблемы, а оно и... "не так страшен черт", если разобраться...

Научиться просто пользовать STL как раз не сложно - достаточно лишь открыть мануал и засунуть тот же array или vector где-нибудь, где как раз лучше обойтись без этого.
А самое сложное - пользоваться разумно именно той сущностью, которой нужно.
Это примерно то же самое, как вкурить когда и где правильно применять паттерн проектирования: по описанию вроде все понятно, но где какой применить - это уже реальная дилемма.
До сих пор многие паттерны для меня - загадка.

Другой пример: масса народу в плюсах по-прежнему пользуется указателями вместо ссылок, а ведь в более новых стандартах указатель практически изжил себя, да он там по-просту не нужен.
Да и сами плюсы многими "программерами" используются в стиле голого си.

Поэтому я уверен, что программист, а точнее - программист-проектировщик - это практически то же самое, что и композитор.
По крайней мере я именно так это воспринимаю: чтобы научится писать музыку, придется изучить и научится исполнять много-много чужой. Одних лишь "мануалов" как читать и писать ноты безусловно тут мало.
Herz
По сути сказанного я с Вами полностью согласен.
Но если моя шутка юмора оказалась неудачной, то я прямо попрошу от Вас (и собеседников) избегать на русскоязычном форуме такого дикого суржика. Ладно ещё, когда без чужеземного заимствования никак не обойтись. Вот, к примеру, недавно одному из форумчан пришлось изобретать "аллокирование", ибо банальное "выделение" или "резервирование", ясно же, никак не годится... biggrin.gif
Но чем буржуазный "экспириенс" ценнее отечественного опыта - ума не приложу...
Forger
Цитата(Herz @ Aug 5 2018, 22:30) *
то я прямо попрошу от Вас (и собеседников) избегать на русскоязычном форуме такого дикого суржика.
Но чем буржуазный "экспириенс" ценнее отечественного опыта - ума не приложу...

Уже давно английский стал неким не побоюсь этого слова всепланетарным языком, особенно в программировании.
В целом с Вами согласен, но с одной поправкой - вместо слова, например, экспириенс стоит использовать иноземное написание: experience.
А иногда, просто лень искать правильное написание того или иного слова в оригинале sm.gif

Herz
Вот именно.
Forger
Цитата(Herz)
чем буржуазный "экспириенс" ценнее отечественного опыта

Слово experience в данном смысле более точно отражает смысл опыта программиста как такового, чем слово "опыт". Более обще, что-ли.
experience <-> опыт в программировании - это примерно то же самое (в моем понимании), как, например, volvo <-> ВАЗ.
Ничего против ВАЗа как такого я не имею, но, думаю, мысль моя понятна sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.