Передать в функцию указатель, а получить указатель на массив

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
Солнцеворот
Встал на лапы
Сообщения: 141
Зарегистрирован: Вт июн 03, 2008 01:39:47

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение Солнцеворот »

[uquote="ARV",url="/forum/viewtopic.php?p=3645124#p3645124"]но я так и не пойму, зачем это делать :([/uquote]
Чтобы процесс передачи-приема данных со стороны main был, как в HAL-библиотеках. Шмякнул функцию, получил ответ в тупом и однозначном виде (и не приходится заглядывать внутрь того ужаса, что понаписали программисты этой библиотеки). Вот тут советуют, что принято это делать через структуры.
ПростоНуб писал(а):Reflector, , исходя из того, что функция в C может возвращать структуру (не указатель на структуру, а именно структуру), то вернуть она может таким образом произвольное количество данных, причем даже различного типа.
В данном случае, использование структуры тоже упростило бы код.
Спасибо за наводку, сейчас сил наберусь новых и попробую тоже.
Реклама
jcxz
Мудрый кот
Сообщения: 1731
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение jcxz »

[uquote="Reflector",url="/forum/viewtopic.php?p=3645140#p3645140"]С -O2 бинарники получились абсолютно одинаковые, а с -O0 этот вариант меньше на 64 байта...[/uquote]
...и что?
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение Reflector »

[uquote="jcxz",url="/forum/viewtopic.php?p=3645190#p3645190"]...и что?[/uquote]
Как минимум то, что без оптимизатора компилятору никакие соглашения о вызове не помогли, там 64 байта разница между реализациями, а полный код еще в 2 раза больше. И наоборот, с оптимизатором для разных подходов получился одинаковый бинарник, т.е. в первую очередь дело именно в нем.

Добавлено after 4 minutes 12 seconds:
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3645160#p3645160"]Reflector, , исходя из того, что функция в C может возвращать структуру (не указатель на структуру, а именно структуру), то вернуть она может таким образом произвольное количество данных, причем даже различного типа.
В данном случае, использование структуры тоже упростило бы код.[/uquote]
У меня структура и возвращается, я бы не стал приводить код на С++ если бы он принципиально отличался от того, что можно сделать на С. Не в этом случае :)
jcxz
Мудрый кот
Сообщения: 1731
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение jcxz »

[uquote="Reflector",url="/forum/viewtopic.php?p=3645216#p3645216"]Как минимум то, что без оптимизатора компилятору никакие соглашения о вызове не помогли, там 64 байта разница между реализациями, а полный код еще в 2 раза больше. И наоборот, с оптимизатором для разных подходов получился одинаковый бинарник, т.е. в первую очередь дело именно в нем.[/uquote]Да, Кэп, никто и не спорил, что оптимизатор делает код меньше. Вопрос был о другом.

PS: И когда хотите сравнить да результата компиляции, то делать это нужно всё-таки по листингу, рассматривая ассемблерные команды. А не по каким-то отвлечённым размерам чего-то не пойми чего...
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ПростоНуб »

Reflector, строго говоря, у Вас возвращается объект класса std::pair, содержащий пару объектов класса void*, конструируемый и инициализируемый внутри вызываемой функции. Вообще классически, надо было тогда создать еще и класс наследник std::pair с нужным методом, а не функцию :)
Я не пытаюсь спорить, что при правильной оптимизации, компилятор и для Вашего варианта, и для моего, сформирует одинаковый машинный код. Но идеологически - это разные решения. Мое - структурное, для С, Ваше - объектно-ориентированное, для C++. Я же не критикую Ваш вариант. Я только указал, что и средствами C он легко реализуется. А уж выберет ТС C или C++ - его дело.
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение Reflector »

[uquote="jcxz",url="/forum/viewtopic.php?p=3645219#p3645219"]Да, Кэп, никто и не спорил, что оптимизатор делает код меньше. Вопрос был о другом.

PS: И когда хотите сравнить да результата компиляции, то делать это нужно всё-таки по листингу, рассматривая ассемблерные команды. А не по каким-то отвлечённым размерам чего-то не пойми чего...[/uquote]
Раз:
Спойлер

Код: Выделить всё

uint64_t func()
{
	void* ptr1 = &var1;
	void* ptr2 = &var2;

	return (uint32_t)ptr1 | (uint64_t)ptr2 << 32;
}

uint64_t q = func();
void* ptr1 = (void*)(uint32_t)q;
void* ptr2 = (void*)(uint32_t)(q >> 32);
И два:
Спойлер

Код: Выделить всё

bl 0x8000914 <func()> 
movs r3, r0 
movs r4, r1 
movs r2, #166
lsls r2, r2, #2 
adds r1, r7, r2 
str r3, [r1, #0] 
str r4, [r1, #4] 
adds r3, r7, r2 
ldr r3, [r3, #0] 
movs r2, #165
lsls r2, r2, #2 
adds r1, r7, r2 
str r3, [r1, #0] 
movs r3, #167
lsls r3, r3, #2 
adds r3, r7, r3 
ldr r3, [r3, #0] 
movs r5, r3 
movs r3, #0 
movs r6, r3 
movs r3, r5 
movs r1, #164
lsls r1, r1, #2 
adds r0, r7, r1 
str r3, [r0, #0] 

push {r4, r5, r6, r7, lr} ;func()
sub sp, #20 
add r7, sp, #0 
ldr r0, [pc, #52]
str r0, [r7, #12] 
ldr r0, [pc, #52]
str r0, [r7, #8] 
ldr r0, [r7, #12] 
movs r1, r0 
movs r0, #0 
movs r2, r0 
ldr r0, [r7, #8] 
movs r5, r0 
asrs r0, r0, #31 
movs r6, r0 
movs r4, r5 
movs r0, #0 
movs r3, r0 
movs r0, r1 
orrs r0, r3 
str r0, [r7, #0] 
orrs r2, r4 
str r2, [r7, #4] 
ldr r3, [r7, #0] 
ldr r4, [r7, #4] 
movs r0, r3 
movs r1, r4 
mov sp, r7 
add sp, #20 
pop {r4, r5, r6, r7, pc} 
Это для M0, но размер все равно впечатляет.

Добавлено after 11 minutes 25 seconds:
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3645226#p3645226"]Reflector, строго говоря, у Вас возвращается объект класса std::pair, содержащий пару объектов класса void*, конструируемый и инициализируемый внутри вызываемой функции. Вообще классически, надо было тогда создать еще и класс наследник std::pair с нужным методом, а не функцию :)[/uquote]
Нет, std::pair без оптимизации привнес бы ощутимый оверхед, потому Pair был другой:

Код: Выделить всё

template<typename T1, typename T2 = T1>
struct Pair { T1 value1; T2 value2; };
Реклама
jcxz
Мудрый кот
Сообщения: 1731
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение jcxz »

[uquote="Reflector",url="/forum/viewtopic.php?p=3645227#p3645227"]Это для M0, но размер все равно впечатляет.[/uquote]
Что-ж - тогда буду так и использовать IAR, а не GCC :)
Раз уж вы про M0, то что говорит AEABI по поводу возврата unsigned long long из функций для M0?
Последний раз редактировалось jcxz Вт июн 04, 2019 18:14:32, всего редактировалось 1 раз.
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ПростоНуб »

Reflector, ну Вы же это не указали в первоначальном посте! Откуда мне было знать, что реализация была на структуре? А какой смысл тогда был говорить о C++, если, де факто, Вы пользовались только средствами C?
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение Reflector »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3645249#p3645249"]Reflector, ну Вы же это не указали в первоначальном посте! Откуда мне было знать, что реализация была на структуре? А какой смысл тогда был говорить о C++, если, де факто, Вы пользовались только средствами C?[/uquote]
ТС пишет на С, возможно стоило и пример со структурой привести на С, но я выбрал вариант на С++ который, тем не менее, от сишного отличается незначительно. Но там есть шаблоны, auto и структурное связывание, т.е. возвращаемый результат присваивается сразу паре переменных, а не структуре, как в оригинальном примере. И да, я же потом написал, что возвращается именно структура :)

[uquote="jcxz",url="/forum/viewtopic.php?p=3645248#p3645248"]Что-ж - тогда буду так и использовать IAR, а не GCC :)[/uquote]
На то он и -O0, с другой стороны для достаточно больших программ -O0 за счет запрета инлайнинга может давать размер меньше чем -O2, не говоря уже о -O3. И никто не заставляет этот -O0 использовать, многие сидят на -Og, хотя у него свои недостатки...
jcxz
Мудрый кот
Сообщения: 1731
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение jcxz »

[uquote="Reflector",url="/forum/viewtopic.php?p=3645265#p3645265"]На то он и -O0, с другой стороны для достаточно больших программ -O0 за счет запрета инлайнинга может давать размер меньше чем -O2, не говоря уже о -O3. И никто не заставляет этот -O0 использовать, многие сидят на -Og, хотя у него свои недостатки...[/uquote]
Разговор вообще не об оптимизации шёл. А о том - можно ли возвращать два значения из функции одновременно? Мануал на IAR говорит, что он будет возвращать 64-битные значения в регистровой паре R0:R1 вне зависимости от уровня оптимизации. Так как такой стиль прописан в AEABI. И если хоть на каком-то уровне оптимизации это не выполняется - это означает несовместимость с AEABI.
Как видно из приведённого Вами листинга, GCC тоже возвращает u64 в регистровой паре R0:R1. Да - промежуточные вычисления он делает на стеке (при оптимизации -O0) и они какие-то очень громоздкие, но здесь речь не об оптимальности кода.

Вывод: Никаких проблем с возвратом двух указателей в виде u64 в R0:R1 не должно быть ни в IAR ни в GCC.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ARV »

проблем-то, может, и не быть, но для чего так делать?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение Reflector »

[uquote="jcxz",url="/forum/viewtopic.php?p=3645731#p3645731"]Мануал на IAR говорит, что он будет возвращать 64-битные значения в регистровой паре R0:R1 вне зависимости от уровня оптимизации. Так как такой стиль прописан в AEABI. И если хоть на каком-то уровне оптимизации это не выполняется - это означает несовместимость с AEABI.[/uquote]
Зайди на сайт ARM и посмотри какие они компиляторы раздают... Для Cortex-A - eabi, для Cortex-M - none-eabi. Собственно таким arm-none-eabi gcc я свой пример и компилировал, потому что никакие линуксы и т.п. я на STM32 запускать не собираюсь :)
jcxz
Мудрый кот
Сообщения: 1731
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение jcxz »

[uquote="ARV",url="/forum/viewtopic.php?p=3645742#p3645742"]проблем-то, может, и не быть, но для чего так делать?![/uquote]А зачем так не делать? :))
Код получается намного меньше, не используется стек и пр. - плюсов много. Минусов - нет.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ARV »

Достоинство ЯВУ только в том, что код получается более лёгким для восприятия.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ПростоНуб »

ARV, а разве возврат функцией структуры так тяжел для восприятия?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ARV »

Структура это следующая ступень абстракции от линейного массива байтов памяти. И эта ступень заключается как раз в том, что вместо ручного вычисления адреса полей структуры вы возлагает это на компилятор, а сами работаете с идентификаторами полей.
А вариант позиционного размещения данных меньшего размера внутри большего, это возврат вниз по уровню абстракции, т.е. отказ от главного достоинства ЯВУ.
Имхо.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ПростоНуб »

ARV, Вы бы посмотрели внимательно на мой код (или код Reflector), прежде чем теории толкать...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ARV »

Мне любопытно: насколько традиционный способ с возвратом через параметры окажется хуже, по сравнению с этим извратом?
<code> void get2param(char **ptr1, char **ptr2);</code>

Добавлено after 1 minute 32 seconds:
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3645869#p3645869"]ARV, Вы бы посмотрели внимательно на мой код (или код Reflector), прежде чем теории толкать...[/uquote]
Я видел вариант с выделением старшего и младшего слов из long-a, это ваш вариант?
Структуру вроде даже не видел...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ПростоНуб »

ARV, тем, что при использовании указателей всегда необходимо выделить в стеке или куче память под то, на что они указывают. А если если функция возвращает несколько значений в одной структуре, помещающейся в регистрах, то это и быстрее, и не требует места в оперативной памяти.

Добавлено after 1 minute 2 seconds:
Re: Передать в функцию указатель, а получить указатель на массив
ARV, у Вас глюки. Посмотрите внимательно на мой код
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Передать в функцию указатель, а получить указатель на ма

Сообщение ARV »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3645875#p3645875"]ARV, у Вас глюки. Посмотрите внимательно на мой код[/uquote]
Вариант с возвратом структуры приемлем вполне. Просто он был на предыдущей странице, а с мобильника неудобно просматривать много.
Мне не понравился вариант с упаковкой указателей в long.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

Вернуться в «ARM»