реклама на сайте
подробности

 
 
> модификатор const. Как правильно использовать в Си
inventor
сообщение Dec 22 2017, 15:39
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



где компилятор должен расположить "переменные"
такого вида:

CODE
// Описано глобально
const u8 x_pos[][8] = {
{50, 60},
{55, 62, 69, 76, 83, 90, 97, 104},
{76},
{76},
};


то же самое, описано внутри функции


и то же самое внутри функции
CODE

static const u8 x_pos[][8] = {
{50, 60},
{55, 62, 69, 76, 83, 90, 97, 104},
{76},
{76},
};



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


в первом варианте в глобальной константе
этот массив помещен в память Flash. Правильное поведение.

Во втором варианте в стек - неправильное
в третьем варианте во Flash память.





Go to the top of the page
 
+Quote Post
8 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 99)
Kabdim
сообщение Dec 22 2017, 16:01
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



rtfm, очень нужно почитать умную книжку по языку на котором разрабатываете.

Модификатор const = сообщение компилятору что бы он проследил что бы код в котором определена эта переменная не пытался менять эти данные. Никаких других гарантий просто const не даёт. А еще бывают такие случаи как например volatile const или const register или const - аргумент функции или преобразования типов при которых cv-модификаторы меняются.
Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно.

Всё увиденное - верное поведение.
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 22 2017, 16:21
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Цитата(Kabdim @ Dec 22 2017, 19:01) *
Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно.

Всё увиденное - верное поведение.



может ли компилятор поместить static const не во flash а в памяти данных?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2017, 16:29
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(inventor @ Dec 22 2017, 19:21) *
может ли компилятор поместить static const не во flash а в памяти данных?

Легко. Причём это поведение описано в стандарте.
Если у флэша и ОЗУ разные адресные пространства именно так и будет.
Например, для AVR специально придуман квалификатор __flash, который укажет компилятору, что данные нужно поместить во флэш, а не в основную память (коей считается ОЗУ).
Для ARM, где единое адресное пространство, можно с уверенностью сказать, что static const данные лягут во флэш (кроме случая когда компилятор решит соптимизировать) .

Умная книга, которую ТС советовали читать - это стандарт языка Си...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Raven
сообщение Dec 22 2017, 16:53
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 491
Регистрация: 16-01-05
Из: Санкт-Петербург
Пользователь №: 1 987



А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2017, 16:56
Сообщение #6


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Raven @ Dec 22 2017, 19:53) *
Нет не должен т.к. .rodata не всегда ассоциируется с FLASH.
Более того в avr-gcc нет секции .rodata

http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
http://www.nongnu.org/avr-libc/user-manual/malloc.html


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 22 2017, 17:00
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(inventor @ Dec 22 2017, 19:21) *
может ли компилятор поместить static const не во flash а в памяти данных?

Теоретически может, но делать этого не будет, т.к. поведение задано настройками.
Если говорить за gcc, то где-то в недрах проекта у вас должен быть файл с расширением *.ld в котором записано что и куда класть. Вы можете его редактировать что бы получить результат отличный от того того что по умолчанию.
Цитата(Raven @ Dec 22 2017, 19:53) *
А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

А линкер может в соответствии со своим скриптом секцию запихнуть туда куда записано в скрипте.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2017, 17:07
Сообщение #8


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Kabdim @ Dec 22 2017, 20:00) *

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

Совершенно легальный код станет невозможен:
Код
char str1[] = "xxx";
const char str2[] = "yyyy";

extern void print_str(const char* str);

print_str(str1);  // норм
print_str(str2);  // попа

Или так будет делать бессмысленно:
Код
volatite const int uptime;

Это я к чему - крутить параметры в скриптах линкера надо не с шашой наголо, а очень и очень вдумчиво...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
k155la3
сообщение Dec 23 2017, 12:07
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Raven @ Dec 22 2017, 19:53) *
А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

Я сразу себя приучил, что компилятор мне ничего не "должен" sm.gif
Особенно в части, если включена оптимизация. И даже если не включена.
Есть много платформо-зависимых ньюансов.
Разобраться, опятьже, помогает RTFM + работа в отладчике с memory-->View.
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 23 2017, 18:03
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



то есть для того что бы константные данные
легли во flash память необходимо
сделать typedef для такого типа:


CODE
typedef const unsigned char cu8;
#define scu8 static cu8
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 23 2017, 19:41
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(demiurg_spb @ Dec 22 2017, 20:07) *
Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.

Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 23 2017, 20:24
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Kabdim @ Dec 23 2017, 22:41) *
Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.

ну да, stm8 дешевле.
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 24 2017, 17:36
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(demiurg_spb @ Dec 22 2017, 22:07) *
Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.
Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры.

Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ?
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 24 2017, 19:04
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(juvf @ Dec 24 2017, 20:36) *
Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры.

Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ?

хотя бы потому, что ICode и Dcode шины разные, мультплексируются. При выборке из флеша медленого к тому же prefetch работает, размещая константы во флеше он сбросится, итого двойной тормоз выйдет.
const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
razrab83
сообщение Dec 25 2017, 03:10
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 5-05-17
Пользователь №: 96 902



Цитата(DASM @ Dec 24 2017, 20:04) *
const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
А почему глобальный конст во флеше, локальный в озу?

Сообщение отредактировал razrab83 - Dec 25 2017, 03:16
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 25 2017, 03:34
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(DASM @ Dec 25 2017, 00:04) *
const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
Да, согласен, но тоже не понятно почему тогда во всех случаях по разному.

Более того, static - это всего лишь указание компилятору, что данные статические, а никак не указание компилятору что и как размещать. Почему со статиком размещаются данные в др месте?
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 25 2017, 07:31
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



еще как указание. статик в теле фции размещается не на стеке, а в общей куче (не путать с кучей malloc). ну и плюс ограничение видимости одной единицей трансляции, если не в теле функции

Цитата(razrab83 @ Dec 25 2017, 06:10) *
А почему глобальный конст во флеше, локальный в озу?

? это самодеятельность компилера на его страх и риск.

собственно если точнее static тоже не говорит где размещать, но определяет время жизни. А уж размещение статик не на стеке - прросто вытекает из этого
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 25 2017, 07:57
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(DASM @ Dec 25 2017, 12:28) *
еще как указание. статик в теле фции размещается не на стеке, а в общей куче (не путать с кучей malloc).

пф.... утверждение осталось, только дополню...

Более того, static - это всего лишь указание компилятору, что данные статические, а никак не указание компилятору что и как размещать, я имел в виду, указание не про кучу и стек, а указание про озу/флешь/еепром/внешнюю память и т.п.

Цитата
это самодеятельность компилера на его страх и риск.
Согласен. В Си/С++ нет ни каких указаний на этот счет. Поэтому разработчики компиляторов на своё усмотрение делают реализацию. И поэтому, если важна область размещения, нужно компиллер контролировать и давать явные указания для размещения данных в нужную память.

Цитата(DASM @ Dec 25 2017, 12:31) *
А уж размещение статик не на стеке - прросто вытекает из этого
Ни чего не вытекает. Статик можно разместить в ОЗУ, а можно разместить в флеше. Конст можно разместить в озу, а можно в флеше. Компилятор волен сам - где и что размещать (в озу или во флешь), и его размещения не поддаются логике.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 25 2017, 08:02
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(juvf @ Dec 25 2017, 10:57) *
его размещения не поддаются логике.

Вполне поддаются и даже описаны в документации.
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 25 2017, 08:15
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(juvf @ Dec 25 2017, 10:57) *
пф.... утверждение осталось, только дополню...

Более того, static - это всего лишь указание компилятору, что данные статические, а никак не указание компилятору что и как размещать, я имел в виду, указание не про кучу и стек, а указание про озу/флешь/еепром/внешнюю память и т.п.

Согласен. В Си/С++ нет ни каких указаний на этот счет. Поэтому разработчики компиляторов на своё усмотрение делают реализацию. И поэтому, если важна область размещения, нужно компиллер контролировать и давать явные указания для размещения данных в нужную память.

Ни чего не вытекает. Статик можно разместить в ОЗУ, а можно разместить в флеше. Конст можно разместить в озу, а можно в флеше. Компилятор волен сам - где и что размещать (в озу или во флешь), и его размещения не поддаются логике.

вытекает что не на стеке
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 25 2017, 08:17
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(DASM @ Dec 25 2017, 13:15) *
вытекает что не на стеке

Причем тут стек? вопрос ТС не про стек, а про флешь vs озу.
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 25 2017, 08:36
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



наверное в следующих стандартах Си это
можно было бы учесть. с const ИМЕю ввиду..
что бы я еще сделал: ввел бы модификатор переменных global
для чего это: предположим в заголовочном файле
мы перечисляем все переменные, которые использует программа
в сегодняшних компиляторах для этого нужно писать в заголовке перменнные с словом extern
и определять сами эти переменные в *.c файле
если в заголовке описать переменные static - то все файлы, которые этот
заголовок включают будут плодить копии этих переменных, что совсем неправильно.
слово global помогло бы этого избежать
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 25 2017, 09:46
Сообщение #23


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Все, что описал топикстартер в начале темы, верно. Нужно понять (и простить). Не хотите, чтобы const переменная переписывалась из ПЗУ в ОЗУ - сделайте ее глобальной. Не нравятся глобальные переменные - сделайте ее статической внутри функции.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2017, 14:08
Сообщение #24


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(juvf @ Dec 24 2017, 20:36) *
Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры.
Если Вы не в теме, то это не означает, что этого нет.
https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gc...-Address-Spaces

В настоящий момент в GCC именно на этой почве случился ступор.
Разработчики avr-gcc не могут сделать так, чтобы по возможности константные данные автоматом ложились во флэш именно из-за того, что стандарт в настоящее время этого не разрешает.

Если интересно - скачайте стандарт c11.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2017, 14:48
Сообщение #25


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Вообще-то в GCC в режиме С (без плюсов) уже года два как поддерживаются разные адресные пространства, в том числе и __flash. А вот в стандарте плюсов их нет, поэтому нет их и в плюсах AVG-GCC, поэтому там ступор, да. А еще - бывают контроллеры вообще без набортного флеша, там и код и константы - все в ОЗУ живет. И к чему все эти споры?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2017, 14:53
Сообщение #26


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Сергей Борщ @ Dec 25 2017, 17:48) *

Я не про плюсы и говорю. И ступор не в плюсах.
Код
const char __flash* const __flash names[] =
{
    "aaa",
    "bbb",
    "ccc"
};

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


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 25 2017, 16:12
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Цитата(Сергей Борщ @ Dec 25 2017, 17:48) *
А еще - бывают контроллеры вообще без набортного флеша, там и код и константы - все в ОЗУ живет. И к чему все эти споры?


cc3200
но там все равно подрузамевается память только для чтения:
CODE
45 190 bytes of readonly code memory
6 072 bytes of readonly data memory
138 267 bytes of readwrite data memory

Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 25 2017, 16:28
Сообщение #28


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата
Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.

Цитата(demiurg_spb @ Dec 25 2017, 19:08) *
Если Вы не в теме, то это не означает, что этого нет.
https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gc...-Address-Spaces

В настоящий момент в GCC именно на этой почве случился ступор.
Разработчики avr-gcc не могут сделать так, чтобы по возможности константные данные автоматом ложились во флэш именно из-за того, что стандарт в настоящее время этого не разрешает.

Если интересно - скачайте стандарт c11.
И? Где в стандарте си основное адресное пространство?
Да даже в по вашей ссылке нет ни каких основных адресных пространств.

ps Это вы не в теме. При чем тут на какойт-о AVR Named Address Spaces? Вопрос не о авр, и даже не о gcc, а о Си.

pps
Цитата
константные данные автоматом ложились во флэш именно из-за того, что стандарт в настоящее время этого не разрешает.

Навыдумывали. В стандарте Си нет даже слова flash. Если интересно - скачайте стандарт c11.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 26 2017, 12:03
Сообщение #29


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



С вами бесполезно разговаривать - это Вы к AVR и flash привязались, не удосужившись прочесть представленные ссылки.
Всё о чём я написал напрямую относится к GCC в общем который, если Вы не в курсе, раньше всех коммерческих продуктов реализует новые возможности языка.
Мы используем в своих разработках GCC для множества архитектур, и по мере возможности делаем его и libc лучше. И мне очень странно слушать Ваши непонятные высказывания.
На этом с Вами разговор считаю законченным, пребывайте в осознании своего всезнания и далее.
Цитата
As an extension, GNU C supports named address spaces as defined in the N1275 draft of ISO/IEC DTR 18037. Support for named address spaces in GCC will evolve as the draft technical report changes. Calling conventions for any target might also change. At present, only the AVR, SPU, M32C, RL78, and x86 targets support address spaces other than the generic address space.

Address space identifiers may be used exactly like any other C type qualifier (e.g., const or volatile). See the N1275 document for more details.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1275.pdf
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1005.pdf

Вдогонку: OpenCL основан на С99 и тоже использует схожие принципы что и Си для ембеда в части адресных пространств.
https://software.intel.com/en-us/articles/t...ce-in-opencl-20


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 27 2017, 02:57
Сообщение #30


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(demiurg_spb @ Dec 26 2017, 17:03) *
написал всё что думаю о вас.... много букв.... удалил....

Вы видите/замечаете/понимаете разницу между "общий" и "основной", между "generic" и "general", между "Programming languages - C" и "Programming languages - C - Extensions to support embedded processors", между "gcc" и "си".


Цитата
принципы что и Си для ембеда
Ого!!! Уже не "Си", а "Си для ембеда". Исправляетесь, значит есть смысл от общения. wink.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 27 2017, 10:12
Сообщение #31


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(juvf @ Dec 27 2017, 05:57) *
Пусть generic - общий. Что от это изменилось? Си он и в африке Си и теперь в нём есть часть (читай глава) затрагивающая ембед.
А на gcc я ссылаюсь от того что это чуть-ли не единственный (ну может быть clang ещё) доступный, открытый и ОЧЕНЬ распространнённый компилятор для огромного количества архитектур.
Люди, разрабатывающие его являются членами комитета, утверждающего и разрабатывающего стандарт Си. Чем не автортет? Не согласны - приведите свои доводы.
Не нравится как я излагаю - читайте прикреплённые мной ссылки на оригиналы статей. Ради этого я их и прилагаю.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 27 2017, 10:49
Сообщение #32


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(demiurg_spb @ Dec 27 2017, 15:12) *
Пусть generic - общий. Что от это изменилось?

Изменилось то, что вы думает об одном, а горите другое.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 27 2017, 10:53
Сообщение #33


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(juvf @ Dec 27 2017, 13:49) *
Изменилось то, что вы думает об одном, а говорите другое.

Согласен. Бываю грешен.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 27 2017, 13:23
Сообщение #34


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Демиург, вы переоцниваете значимость техникал репортов. Переводя на русский это законопроект, который отнюдь не обязательно станет законом. Собственно в итоге не включают в станадарт большинство техникал репортов. Даже тех которые заметно более полезные чем выше перечисленные.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 27 2017, 13:24
Сообщение #35


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Время покажет. Факт есть факт - в gcc уже реализовано и мало помалу обкатывается.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 27 2017, 14:34
Сообщение #36


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



мдя
задал простой вопрос
и как всегда разгорелся срач на ровном месте
Go to the top of the page
 
+Quote Post
pnp_mechanic
сообщение Dec 27 2017, 15:14
Сообщение #37


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 25-07-17
Пользователь №: 98 462



Вставлю и я свои 5 коп.
Inventor, всегда можно посмотреть адрес конкретной переменной.
Или константы . Средства Си это отлично могут делать.
Go to the top of the page
 
+Quote Post
aiwa
сообщение Dec 27 2017, 16:08
Сообщение #38


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(inventor @ Dec 25 2017, 10:36) *
....в сегодняшних компиляторах для этого нужно писать в заголовке перменнные с словом extern

слово global помогло бы этого избежать


По количеству нажатий global ничем не лучше extern.
Зачем плодить синонимы?

Go to the top of the page
 
+Quote Post
Quasar
сообщение Dec 30 2017, 09:04
Сообщение #39


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(razrab83 @ Dec 25 2017, 06:10) *
А почему глобальный конст во флеше, локальный в озу?



Локальная const переменная может инициализироваться в момент вызова функции и на стадии сборки неизвестна. Нечего класть во флеш. А вот static const и глобальная const переменная известны уже на стадии сборки.

PS: у меня однажды с одним коллегой драма случилась, он мне долго доказывал, что const ложится всегда исключительно в ro секцию (типа константа ЖЕ) и меняться в процессе исполнения не может (так как либо это флеш, либо область защищенная MMU). Если общение было в тот момент не по переписке, думаю и до мордобития дошло бы дело smile3009.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 1 2018, 18:44
Сообщение #40


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Про применение volatile const для read only регистров переферии уже упоминалось?
Кажется это довольно яркая демонстрация того, что const гарантирует в первую очередь ошибку компилятора при попытке что-то записать в такую переменную, а всё остальное это уже побочные эффекты, оптимизации и здравый смысл разработчиков компилятора.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 2 2018, 08:55
Сообщение #41


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(sigmaN @ Jan 1 2018, 21:44) *
Про применение volatile const для read only регистров переферии уже упоминалось?
Кажется это довольно яркая демонстрация того, что const гарантирует в первую очередь ошибку компилятора при попытке что-то записать в такую переменную, а всё остальное это уже побочные эффекты, оптимизации и здравый смысл разработчиков компилятора.


Я в свое время добавил вопрос о const в список вопросов для соискателей на собеседовании. Удивительно было то, что порой люди с опытом 5 лет и более, ничего кроме "const это константа неизменяемая" сказать не могут. А случай когда регистр периферии volatile const они обычно называют каким-то искусственным и притянутым за уши.

Go to the top of the page
 
+Quote Post
razrab83
сообщение Jan 3 2018, 10:26
Сообщение #42


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 5-05-17
Пользователь №: 96 902



Цитата(Quasar @ Dec 30 2017, 09:04) *
Локальная const переменная может инициализироваться в момент вызова функции и на стадии сборки неизвестна. Нечего класть во флеш. А вот static const и глобальная const переменная известны уже на стадии сборки.
Локальная const переменная на стадии сборки известна.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 3 2018, 10:53
Сообщение #43


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Код
int f(int a )
{
const int c = 5;
return a + c;
}
Цитата
Локальная const переменная на стадии сборки известна.

Сделали такой вывод потому, что можете видеть = 5 своими глазами? wink.gif

Выразимся точнее
Переменная c при любой настройке компилятора не ляжет во флеш потому, что у нее не static storage duration.
Переменная c вообще не займет никакой памяти(даже на стеке) при включении оптимизации.
Ознакомьтесь с
https://en.wikipedia.org/wiki/Constant_folding


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
razrab83
сообщение Jan 3 2018, 13:47
Сообщение #44


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 5-05-17
Пользователь №: 96 902



Цитата
Переменная c вообще не займет никакой памяти(даже на стеке)
Как раз таки переменная c займет память программ.

int f(int a )
{//при входе а копируем в аккумулятор
const int c = 5;//этой строки в коде вообще может не быть.
return a + c;//здесь будет выполнен может быть выполнен код типа такого add acc,#5, где #5 - это и есть наша const int c, и эта пятерка лежит во флешь.
}
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 3 2018, 18:26
Сообщение #45


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Ну так мы же про размещение данных говорим вроде как.
Цитата
return a + c;//здесь будет выполнен может быть выполнен код типа такого add acc,#5, где #5 - это и есть наша const int c, и эта пятерка лежит во флешь.
Кстати говоря эта пятерка уже не переменная. Она станет частью инструкции в общем случае называемой Add Immediate. Т.е. не пятерка займет флеш, а инструкция у котой нужные биты будут равны пятерке.
Так что не будем путать тёплое с мягким. Во флеше пятерки нет - есть инструкция, куда она входит.

А если в вышеуказанном примере сделать const int с = 1 то вообще интересно может получится - вместо этого будет сгенерирована какая-нибудь инструкция
Код
inc acc
которая инкрементирует аккумулятор.
Тоже скажете, что константа во флеше?


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 3 2018, 22:06
Сообщение #46


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(razrab83 @ Jan 3 2018, 13:26) *
Локальная const переменная на стадии сборки известна.



Тогда подумайте и попробуйте собрать этот код:

Код
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

void foo ( uint32_t in ) {
    const uint32_t test = in;
    const uint32_t *pTest = &test;

    printf ( "%d, %p\n", test, pTest );

}

int main ( void ) {
    time_t t;
    
    srand((unsigned) time(&t));

    foo ( 55 );
    foo ( 77 );

    foo ( rand() % 100 );

    return 0;
}
Go to the top of the page
 
+Quote Post
razrab83
сообщение Jan 4 2018, 08:50
Сообщение #47


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 5-05-17
Пользователь №: 96 902



Цитата(sigmaN @ Jan 3 2018, 18:26) *
Тоже скажете, что константа во флеше?
Да. С точки зрения Си константа есть, а как там её компилятор реализовал - это уже дело компилятора.

2Quasar
Код
const uint32_t test = in;
убедили. такая константа инитится во время выполнения. Но "const uint32_t test = 5;" инитится известна при компиляции.
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 4 2018, 21:57
Сообщение #48


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(razrab83 @ Jan 4 2018, 11:50) *
2Quasar
Код
const uint32_t test = in;
убедили. такая константа инитится во время выполнения. Но "const uint32_t test = 5;" инитится известна при компиляции.


Конкретно ваша "const uint32_t test = 5" соптимизируется непонятно во что. Но компилятор действует "в общем". А "в общем", модификатор const - гарант того, что конструкция "a = 5" вне блока инициализации невалидна. Остальное - следствие здравого смысла. Если можно const переменную убрать в rodata (FLASH или ro ОЗУ), её туда уберут, если нельзя - то нет, не уберут.
Go to the top of the page
 
+Quote Post
inventor
сообщение Jan 25 2018, 11:54
Сообщение #49


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



читаю pdf на IAR
такой забавный пример с константами:
Цитата
String literals and other constants can be avoided by using initialized variables. For
example, the following lines:

CODE

__ramfunc void test()
{
/* myc: initializer in ROM */
const int myc[] = { 10, 20 };
/* string literal in ROM */
msg("Hello");
}

Цитата
can be rewritten to:

CODE

__ramfunc void test()
{
/* myc: initialized by cstartup */
static int myc[] = { 10, 20 };
/* hello: initialized by cstartup */
static char hello[] = "Hello";
msg(hello);
}
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 25 2018, 14:36
Сообщение #50


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Правильно, потому что это __ramfunc и никто не хочет чтоб "Hello" занимало оперативку


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 25 2018, 15:26
Сообщение #51


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sigmaN @ Jan 25 2018, 17:36) *
Если __ramfunc, то как раз все данные должны быть только в оперативке...
Например бутлоадер, который пишет во flash, не должен затрагивать данных из того-же flash.
Поэтому проще было убрать в приведённом примере слово static и слово const вовсе - результат был бы такой же, а буков меньше.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
krux
сообщение Jan 25 2018, 16:40
Сообщение #52


Профессионал
*****

Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596



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


--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 25 2018, 17:09
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Quasar @ Jan 2 2018, 11:55) *
Я в свое время добавил вопрос о const в список вопросов для соискателей на собеседовании. Удивительно было то, что порой люди с опытом 5 лет и более, ничего кроме "const это константа неизменяемая" сказать не могут. А случай когда регистр периферии volatile const они обычно называют каким-то искусственным и притянутым за уши.

а он и есть приятнут за уши. Привидите плиз пример когда volatile const необходим и заоодно выдержку из стандарта где поведение этой конструкции описывается. Реально раздражают такие собеседователи с дебильными "что значит const char * const blavbla". Еще бы про auto спрашивали, который не впился ни в одно место эмеддерам ни в эпоху С, ни в эпоху С++ 14 когда он стал значить совершенно иное
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 25 2018, 20:20
Сообщение #54


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Правильно, потому что это __ramfunc и никто не хочет чтоб "Hello" занимало оперативку

Упс. Не заметил, что в примере локальные статики без const. Действительно hello будет в RAM, что действительно логично для __ramfunc.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 26 2018, 11:12
Сообщение #55


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(krux @ Jan 25 2018, 19:40) *
приведенный выше пример справедлив, например, когда есть тормозная флешка и быстрая и большая внешняя DDR. тогда cstartup как раз скопирует константу, к которой нужен быстрый и частый доступ в DDR.
В таких система обычно весь flash без разбора копируется в ОЗУ задолго да cstartup.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jan 27 2018, 09:35
Сообщение #56


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(DASM @ Jan 25 2018, 20:09) *
Еще бы про auto спрашивали, который не впился ни в одно место эмеддерам


Прошу заменять все Ваши сентенции "никому не нужен ..." на "мне не нужен".
Спасибо.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 27 2018, 11:25
Сообщение #57


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(esaulenka @ Jan 27 2018, 12:35) *
Прошу заменять все Ваши сентенции "никому не нужен ..." на "мне не нужен".
Спасибо.

хорошо, мне не нужен auto в С. Вам нужен?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 27 2018, 20:24
Сообщение #58


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Не знаю, что он нынче делает в C, а в плюсах новый auto использую очень часто и нахожу очень удобным.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 27 2018, 20:38
Сообщение #59


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Сергей Борщ @ Jan 27 2018, 23:24) *
Не знаю, что он нынче делает в C, а в плюсах новый auto использую очень часто и нахожу очень удобным.

Да, я про С имел в виду более. В С++ и const собственно гораздо важнее и нужнее. Просто само использование плюсов в эмбеддед ранее было сильно ограничено так сказать, свободно с STL стало писать можно относительно недавно, когда ОЗУ достаточно (256 К и более)
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 28 2018, 09:14
Сообщение #60


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата
Привидите плиз пример когда volatile const необходим и заоодно выдержку из стандарта где поведение этой конструкции описывается.


Поведение volatile описано, поведение const тоже. Дерзайте, соединяйте вместе.

Участок одного из заголовочных файлов к STM32. Определение для __I и для __IO найдете сами. Хотя естественно можно с const не заморачиваться, также, как и с осмысленными именами функций, например.

Можно развить ваш вопрос: "приведите пример, когда const необходим и без него никак"?

Код
typedef struct
{
  __IO uint32_t POWER;          /*!< SDIO power control register,    Address offset: 0x00 */
  __IO uint32_t CLKCR;          /*!< SDI clock control register,     Address offset: 0x04 */
  __IO uint32_t ARG;            /*!< SDIO argument register,         Address offset: 0x08 */
  __IO uint32_t CMD;            /*!< SDIO command register,          Address offset: 0x0C */
  __I uint32_t  RESPCMD;        /*!< SDIO command response register, Address offset: 0x10 */
  __I uint32_t  RESP1;          /*!< SDIO response 1 register,       Address offset: 0x14 */
  __I uint32_t  RESP2;          /*!< SDIO response 2 register,       Address offset: 0x18 */
  __I uint32_t  RESP3;          /*!< SDIO response 3 register,       Address offset: 0x1C */
... etc

} SDIO_TypeDef;


Цитата(DASM @ Jan 25 2018, 20:09) *
а он и есть приятнут за уши.


А какие вопросы вы считаете не притянутыми за уши для программиста встроенных систем с опытом хотя бы более 5 лет?

Мне всегда интересно понять, как человек думает. Даже если умный человек столкнулся первый раз с такой конструкцией (а это вполне возможно), он задумается, постарается понять, о чем речь. Неумный начнет доказывать, разбрасывая слюни в разные стороны, что оно не надо, вы все тут идиоты, так никто не программирует! Но этот человек пришел к нам, решать наши задачи за деньги. Сейчас задача понять, что значит volatile const, вот и все.

Бывают и совсем волшебные кандидаты, которые даже вопрос не понимают, а пишут опыт 100500 лет и более.


Цитата(Сергей Борщ @ Jan 27 2018, 23:24) *
Не знаю, что он нынче делает в C, а в плюсах новый auto использую очень часто и нахожу очень удобным.


В C++ крайне нужная весчЬ.

Хотя в C++ я не использую это слово по старой привычке, и опираясь на логику некоторых местных товарищей, могу утверждать, что оно не нужно :-)
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 28 2018, 17:09
Сообщение #61


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



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

Сообщение отредактировал Arlleex - Jan 28 2018, 17:12
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 28 2018, 17:44
Сообщение #62


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Arlleex @ Jan 28 2018, 20:09) *
Ну, чтобы совсем подлить масла в огонь, можно вбросить "имя двумерного массива не есть указатель на указатель" и "имя массива и указатель это разные вещи".
Или, например, "константный указатель это не то же самое что указатель на константу"...
И действительно, есть люди которые в упор не видят разницу, когда она там есть.

Ну указатель то как раз ясно, а вот с остальным так себе...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 28 2018, 19:50
Сообщение #63


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Код
int arr[2] = {0, 1};
int i;
int pi;

int *ptr = arr;
int ptri;

int main(void)
{
    i = arr[1];
    pi = *arr+1;
    ptri = ptr[1];
    if( (i == pi) == ptri )
        asm("nop");
    /* Replace with your application code */
    while (1)
    {
    }
}

Для затравки кусок кода:
Брэйкпоинт установленный на nop сработает? Сработает. Значит массив это указатель? А указатель это массив? wink.gif

На много интереснее попросить привести примеры где именно массив поведет себя иначе чем указатель и наоборот.

Кто ответит? )


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
gerber
сообщение Jan 28 2018, 20:03
Сообщение #64


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(sigmaN @ Jan 28 2018, 22:50) *
Брэйкпоинт установленный на nop сработает? Сработает.

Не сработает.

Сообщение отредактировал gerber - Jan 28 2018, 20:04


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 28 2018, 20:40
Сообщение #65


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(gerber @ Jan 28 2018, 23:03) *
Не сработает.

Сработает!
Только вот за конструкции видаif ((i == pi) == ptri) лучше отрубать голову голову сразу. Такой код гораздо хуже случая, когда программер не разбирается в const volatile
Гм, а как эта строка вообще работает то ?
http://www.includehelp.com/c/how-expressio...rogramming.aspx


Гыыы int arr[2] = { 0, 1 }; Ай маладца, а если nt arr[2] = { 0, 2 }; ?
Не, реально 10 лет без права переписки за такие хаки
The result of (a==cool.gif is 1 (i.e. true). И еще - по стандарту true совсем не обязан быть 1

Строка сравнивает числовое значение true , обычно 1, со значением из массива по первому индексу... глубокомысленно
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 28 2018, 20:51
Сообщение #66


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Я думаю стоит сконцентрироваться на работе с массивом и индексами, сравнением массива с указателями.

Ответа на вполне конкретный вопрос пока не поступило.
Цитата
На много интереснее попросить привести примеры где именно массив поведет себя иначе чем указатель и наоборот.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 28 2018, 21:15
Сообщение #67


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(sigmaN @ Jan 28 2018, 23:51) *
Ответа на вполне конкретный вопрос пока не поступило.


sizeof ( ptr ) != sizeof ( arr )

biggrin.gif
Go to the top of the page
 
+Quote Post
alx.bilous
сообщение Jan 28 2018, 21:31
Сообщение #68


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 18-03-12
Пользователь №: 70 865



Цитата(sigmaN @ Jan 28 2018, 22:50) *
На много интереснее попросить привести примеры где именно массив поведет себя иначе чем указатель и наоборот.

https://ideone.com/SLqzMw
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 28 2018, 21:34
Сообщение #69


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Ну имя массива это не lvalue , нельзя записать "имя_массива++" например. А указатель - lvalue

Цитата(alx.bilous @ Jan 29 2018, 00:31) *

prog.c:8:4: error: assignment to expression with array type
a = b;
VS дает на такое именно " error C2106: '=' : left operand must be l-value"

Цитата(sigmaN @ Jan 28 2018, 23:51) *
Я думаю стоит сконцентрироваться на работе с массивом и индексами, сравнением массива с указателями.

Ответа на вполне конкретный вопрос пока не поступило.

Так а кусок кода что Вы привели - какой смысл имеет и какое отношение к этому? Он попросту ошибочен
Go to the top of the page
 
+Quote Post
alx.bilous
сообщение Jan 28 2018, 21:38
Сообщение #70


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 18-03-12
Пользователь №: 70 865



Мне и правда нужно было упоминать что строка девять и строка восемь это тот случай когда "массив поведет себя иначе чем указатель"?
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 29 2018, 05:42
Сообщение #71


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата
На много интереснее попросить привести примеры где именно массив поведет себя иначе чем указатель и наоборот.

Кто ответит? )

Я отвечу. Ознакомьтесь. laughing.gif

Сообщение отредактировал Arlleex - Jan 29 2018, 05:58
Go to the top of the page
 
+Quote Post
sidy
сообщение Jan 29 2018, 06:52
Сообщение #72


Местный
***

Группа: Участник
Сообщений: 280
Регистрация: 2-11-08
Пользователь №: 41 333



Цитата(Quasar @ Jan 28 2018, 12:14) *
В C++ крайне нужная весчЬ.

Хотя в C++ я не использую это слово по старой привычке, и опираясь на логику некоторых местных товарищей, могу утверждать, что оно не нужно :-)

Очень нужная весчЬ - использовать я ее конечно не буду rolleyes.gif
Go to the top of the page
 
+Quote Post
_Sam_
сообщение Jan 29 2018, 07:45
Сообщение #73


Местный
***

Группа: Свой
Сообщений: 278
Регистрация: 18-01-05
Из: Санкт-Петербург
Пользователь №: 2 031



Цитата
в первом варианте в глобальной константе
этот массив помещен в память Flash. Правильное поведение.

Во втором варианте в стек - неправильное
в третьем варианте во Flash память.


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

Цитата
На много интереснее попросить привести примеры где именно массив поведет себя иначе чем указатель и наоборот.

К имени массива привязан не только адрес, но и размер. Как уже писали выше размеры массива и указателя не равны.
Код
#include <iostream>
using namespace std;
uint32_t na[] = {0,1};
uint32_t *a = na;

int main() {
    if(sizeof(a) == sizeof(na))
       cout << "equal";
    else
       cout << "not equal";
    // your code goes here
    return 0;
}


Еще пример когда в качестве параметра передается ссылка на массив, в этом случае указатель в качестве параметра не пройдет.
Цитата
void func(uint32_t (&na)[2])



Go to the top of the page
 
+Quote Post
Kabdim
сообщение Jan 29 2018, 08:19
Сообщение #74


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(sigmaN @ Jan 28 2018, 22:50) *
Кто ответит? )

Даже зная как найти ответ всегда хотелось настучать по голове непризнанным гениям ставящим это и подобное на собеседовании. Ну и уж точно не пошел бы контору где такие вопросы задают.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jan 29 2018, 09:14
Сообщение #75


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(_Sam_ @ Jan 29 2018, 12:45) *
Второй вариант отличается тем, что массив живет только во время вызова функции, поэтому запихивать его пожизненно во флэш нелогично.
Он в любом случае пожизненно живет во флеш... до вызова функции он живет только во флеш, во время вызова живет и в ОЗУ и во флеш.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 29 2018, 12:21
Сообщение #76


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(juvf @ Jan 29 2018, 12:14) *
Он в любом случае пожизненно живет во флеш... до вызова функции он живет только во флеш, во время вызова живет и в ОЗУ и во флеш.

Во флэш он не живет, а существует хранится. laughing.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 29 2018, 15:04
Сообщение #77


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Kabdim @ Jan 29 2018, 11:19) *
Даже зная как найти ответ всегда хотелось настучать по голове непризнанным гениям ставящим это и подобное на собеседовании. Ну и уж точно не пошел бы контору где такие вопросы задают.

+++! А какой у них при этом умный вид! Как правило это всякие КТН, с напускным видом умудренного опытом жирного кота. Если посмотреть потом их код - как правило это академическая муть с неочевидной перегрузкой операторов, неуклюжей попыткой засунуть ООП там, где оно вообще не надо итп. Реально полезного - ноль, собственно поэтому и ищут людей ))
Правда это не случай Сигмы - тут обратное , код похож на тот, что напишет бывший ассемблирщик, которому дали С. Причем с ошибкой (или это тест на внимание такой? )
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 29 2018, 15:46
Сообщение #78


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Код
int (*ptr)[2];

Скомпилится?
ptr это массив поинтеров?
Поинтер на массив?
Ваш варинт ответа wink.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 29 2018, 15:55
Сообщение #79


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(sigmaN @ Jan 29 2018, 18:46) *
Код
int (*ptr)[2];

Скомпилится?
ptr это массив поинтеров?
Поинтер на массив?
Ваш варинт ответа wink.gif

это вот что https://www.youtube.com/watch?v=cdX8r3ZSzN4 sm.gif
А так то - указатель на массив, только вот по-моему редко кто такими конструкциями пользуется.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jan 29 2018, 16:01
Сообщение #80


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(ViKo @ Jan 29 2018, 17:21) *
Во флэш он не живет, а существует хранится. laughing.gif
для эстетов
Он в любом случае пожизненно хранится (занимает память) во флеш... до вызова функции он храниться (занимает память) во флеш, во время вызова хранится (занимает память) и в ОЗУ и во флеш.laughing.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 29 2018, 16:37
Сообщение #81


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



delete
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 29 2018, 19:35
Сообщение #82


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(sigmaN @ Jan 29 2018, 18:46) *
Код
int (*ptr)[2];

Скомпилится?
ptr это массив поинтеров?
Поинтер на массив?
Ваш варинт ответа wink.gif

Указатель на массив.

Теперь моя очередь =)

Код
char (*(*func(void))[3])(void);

Цитата
Скомпилится?
Ваш варинт ответа wink.gif

biggrin.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 29 2018, 21:07
Сообщение #83


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



А вот это я расшифровать пока не могу blink.gif

Озвучу мысли, но я не уверен что это правильно
func это массив указателей на функцию без параметров, которая возвращает указатель на фукнцию без параметров, которая возвращает char


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 29 2018, 21:14
Сообщение #84


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(sigmaN @ Jan 30 2018, 00:07) *
А вот это я расшифровать пока не могу blink.gif

Озвучу мысли, но я не уверен что это правильно
func это массив указателей на функцию без параметров, которая возвращает указатель на фукнцию без параметров, которая возвращает char

Ну, я Вас понимаю =)
Подобные "сюрпризы" ни раз приходилось наблюдать в индусских говнопрограммах драйверах для процессоров различных платформ.
Пример надуманный, и у вышеупомянутых коллек по ремеслу индусских товарищей было что-то чуть-чуть попроще, но лишь чуть-чуть laughing.gif
P.S. func - это функция, не принимающая аргументов и возвращающая указатель на массив указателей на функции, которые возвращают char и не принимают параметров.

Кстати, кто там хотел проверять кандидатов на знание языка Си - да элементарно предложите написать окружение для безошибочного компилирования следующей белиберды
Код
for(;P("\\n"),R-;P("|"))for(e=C;e-;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);

Этой строке лет 20 уже - как гласит легенда - "первоапрельская шутка для UNIX-программистов" раньше была...
Это покажет уровень понимания (!) языка в принципе. Я знаю, что знание языка отнюдь не всегда самое важное, однако эмбеддерам мое мнение нахрен никому не нужно считаю нужно уметь "думать" на языке, на котором пишешь.

Сообщение отредактировал Arlleex - Jan 29 2018, 21:21
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 29 2018, 21:20
Сообщение #85


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Arlleex @ Jan 30 2018, 00:14) *
Ну, я Вас понимаю =)
Подобные "сюрпризы" ни раз приходилось наблюдать в индусских говнопрограммах драйверах для процессоров различных платформ.
Пример надуманный, и у вышеупомянутых коллек по ремеслу индусских товарищей было что-то чуть-чуть попроще, но лишь чуть-чуть laughing.gif
P.S. func - это функция, не принимающая аргументов и возвращающая указатель на массив указателей на функции, которые возвращают char и не принимают параметров.

Ну блин, я к Вам в кино в следущий раз подсяду и буду шептать "а убийца то - дворник. " Только я тоже пока не могу корректно компилящийся код под такую конструкцию написать, даже после такого ответа. Возникает идея - давать на собеседовании такие вот вопросы, и, если решил - не брать ни в коем случае, а то весь код в таком ключе и будет написан. Шарады и ребусы это конечно круто, но не в рабочем коде. А вообще это все ерунда я считаю. Пусть не знает вообще ни одного языка, но нарисует мне удобные интерфейсы - это супер. Я вот уже месяц торможу над проектом, при этом основной инструмент - планшет с пером, рисую взаимосвязи и интерфейсы, вот там реально мало чую у меня опыта. А эти шарады нафик не сдались
"понимания (!) языка в принципе." - ничего кроме знания формальных правил это не покажет. Давайте ужо кодера от программиста отличать что-ли
Задумался "нужно уметь "думать" на языке" - а чтобы думать всегда надо думать словами ? Двуязычные тут есть? На каком языке думаете обычно? Я про реальные языки, типа русского там или украинского, английского.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 29 2018, 21:27
Сообщение #86


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(DASM @ Jan 30 2018, 00:20) *
Ну блин, я к Вам в кино в следущий раз подсяду и буду шептать "а убийца то - дворник. " Только я тоже пока не могу корректно компилящийся код под такую конструкцию написать, даже после такого ответа. Возникает идея - давать на собеседовании такие вот вопросы, и, если решил - не брать ни в коем случае, а то весь код в таком ключе и будет написан. Шарады и ребусы это конечно круто, но не в рабочем коде. А вообще это все ерунда я считаю. Пусть не знает вообще ни одного языка, но нарисует мне удобные интерфейсы - это супер. Я вот уже месяц торможу над проектом, при этом основной инструмент - планшет с пером, рисую взаимосвязи и интерфейсы, вот там реально мало чую у меня опыта. А эти шарады нафик не сдались

Вам лично могу придумать полдесятка витиеватых примеров для решения rolleyes.gif

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

Многие "фишки" C++ как раз раскрываются вот такими интересными конструкциями... Тот же механизм виртуальных функций...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 29 2018, 21:31
Сообщение #87


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
func - это функция, не принимающая аргументов и возвращающая указатель на массив указателей на функции, которые возвращают char и не принимают параметров.
А, точно. Немного запутался


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 29 2018, 21:34
Сообщение #88


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Arlleex @ Jan 30 2018, 00:27) *
Вам лично могу придумать полдесятка витиеватых примеров для решения rolleyes.gif

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

Многие "фишки" C++ как раз раскрываются вот такими интересными конструкциями... Тот же механизм виртуальных функций...

Вот после такой хрени таки да, auto как глоток воздуха становится. Ловлю себя на мысли, что то , чем не пользуешься - забывается мгновенно. Я синтаксис того что Вы написали однозначно не прочел бы ни с первого ни второго раза. В реальной работе крайне редко использую даже простой указатель на функцию. Если нужен - снова гуглю - где там скобочки и звездочки правильно расставить надо. Честно говоря такая моя "безграмотность" - не мешает. Проектирование программы, повторюсь, считаю куда более сложной задачей, чем собственно претворение готового проекта в код
"использовать приходилось, да и решение выглядело вполне изящно" - да, согласен. Но я такие конструкции с гуглом пишу а не по памяти, обычно их пару раз в моих небольших проектах то и нужно всего использовать.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 29 2018, 21:57
Сообщение #89


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(DASM @ Jan 30 2018, 00:34) *
Вот после такой хрени таки да, auto как глоток воздуха становится. Ловлю себя на мысли, что то , чем не пользуешься - забывается мгновенно. Я синтаксис того что Вы написали однозначно не прочел бы ни с первого ни второго раза...
Честно говоря такая моя "безграмотность" - не мешает. Проектирование программы, повторюсь, считаю куда более сложной задачей, чем собственно претворение готового проекта в код...

Насчет проектирования программы с Вами полностью согласен.
Я просто люблю разные "трюки" в Си. Но стараюсь их избегать в реальном применении, потому как понимаю, что мой код, возможно, кому-то еще и поддерживать.
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 29 2018, 22:09
Сообщение #90


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



"кому-то еще и поддерживать." и 99 % это вы сами и будете, чертыхаясь и пытаясь понять свой же код. Я - за хорошие названия переменных и методов, вот тут тоже думать много надо над именем, (хотя собственно эти имена и отражают стадию проектирования). И если они хорошие - методы не нуждаются в комментариях (самодокометированный код_) за редким исключением. Еще думать как лучше вернуть несколько значений, раньше я передавал указатели, которые метод заполнял. Сейчас чаще завожу структуру отдельную и возращаю ее. Если структура выглядит как смесь совершенно несвязанных вещей - значит и метод у меня неправильный задуман, и его надо разбивать на несколько мелких более. В общем чем больше пишу, тем более простой код стараюсь делать, избегаю сложных конструкций в одну строку (зачем ? хвастать что можешь так ? перед самим собой что-ли?). Не стеснятся goto в меру . Лучше написать "туповатый" код но понятный даже новичку в С, чем вычурную констркцию if( (i == pi) == ptri ) и не заметить что первая ее часть возращает bool который ты ошибочно сравниваешь с int и это работает.. если int равен 1 и только.. как-то так.. а уж какие горы в ++ можно навернуть то это жуть. Страуструп признавался, что знает С++ где-то на 80..90 из 100. Куда уж смертным то
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 30 2018, 05:07
Сообщение #91


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Мудреные конструкции наподобие вышеприведенных разбираются в учебнике K&R "Язык C", там и метод описан. В жизни мне использовать нет необходимости.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jan 30 2018, 05:14
Сообщение #92


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Arlleex @ Jan 30 2018, 04:14) *
P.S. func - это функция, не принимающая аргументов и возвращающая указатель на массив указателей на функции, которые возвращают char и не принимают параметров.

func - не функция, а указатель на функцию.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 30 2018, 05:16
Сообщение #93


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(DASM @ Jan 29 2018, 18:04) *
+++! А какой у них при этом умный вид! Как правило это всякие КТН, с напускным видом умудренного опытом жирного кота. Если посмотреть потом их код - как правило это академическая муть с неочевидной перегрузкой операторов, неуклюжей попыткой засунуть ООП там, где оно вообще не надо итп. Реально полезного - ноль, собственно поэтому и ищут людей ))


Стоит заметить, что ваши личные комплексы не являются темой данного обсуждения. Если у вас есть какие-то жизненные упущения, как то неполученный статус КТН, например, можете завести отдельную тему, где поплачитесь, а мы вас подбодрим добрым словом.

biggrin.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 30 2018, 06:04
Сообщение #94


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



"поплачИтесь" ,- непременно

Цитата(dxp @ Jan 30 2018, 08:14) *
func - не функция, а указатель на функцию.

Совсем ничего не соображаю, а почему такая запись возможно тогда?
CODE
char(*(*func(void))[3])(void)
{
char(*(*f)[3]) (void) = NULL;
return f;
}
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 30 2018, 06:37
Сообщение #95


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(dxp @ Jan 30 2018, 08:14) *
func - не функция, а указатель на функцию.

Вы не правы.

Цитата
Совсем ничего не соображаю, а почему такая запись возможно тогда?
CODE
char(*(*func(void))[3])(void)
{
char(*(*f)[3]) (void) = NULL;
return f;
}

Потому что func - это то, что я писал выше. А вот f - это указатель на массив указателей на функции. Записи логически и синтаксически корректны.

Сообщение отредактировал Arlleex - Jan 30 2018, 07:55
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 30 2018, 07:49
Сообщение #96


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(DASM @ Jan 30 2018, 09:04) *
"поплачИтесь" ,- непременно


Ваше замечание притянуто за уши. Поскольку Я применяю это слово редко (или не применяю вовсе), могу делать в нем столько ошибок, сколько захочу. Я же не яйцеголовый КТН в самом деле! И если меня кто-то на собеседовании поправит, обязательно настучу по голове, как было предложено выше.
Go to the top of the page
 
+Quote Post
DASM
сообщение Jan 30 2018, 08:00
Сообщение #97


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Arlleex @ Jan 30 2018, 09:37) *
логически и синтаксически корректны.

жаль что совершенно нечитаемы (мне). Всегда удивляют (приятно) люди (на Хабре например) которые это щелкают как орехи. Не понимаю, как при обычном программировании можно получить опыт чтения такого.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jan 30 2018, 09:08
Сообщение #98


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Arlleex @ Jan 30 2018, 13:37) *
Вы не правы.

char (*(*func(void))[3])(void);

да, не указатель (проглядел скобки справа), но это и не функция. sm.gif Строго говоря, func - есть имя функции, которое семантически является её адресом, т.е. технически это указатель. Всё выражение да, не указатель, но, строго, и не функция.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Quasar
сообщение Jan 30 2018, 09:11
Сообщение #99


Местный
***

Группа: Свой
Сообщений: 257
Регистрация: 2-12-06
Из: Default City
Пользователь №: 23 021



Цитата(Arlleex @ Jan 30 2018, 00:14) *
P.S. func - это функция, не принимающая аргументов и возвращающая указатель на массив указателей на функции, которые возвращают char и не принимают параметров.


Припомнил у себя в проекте такой же код, правда только после того, как вы на русском дали разъяснение по своему примеру. Там все было сделано через typedef и по сути даже более сложная структура была.

Мое мнение, подобная бадяга (указатель, на указатель на функцию возвращающую массив указателей тра-ля-ля...) может применятся очень часто, вопрос только в том, как оно оформлено.

Код
typedef int32_t /*successful = 0*/ ( *callback_func_t ) ( uint32_t /*protocol status*/ );

typedef callback_func_t callback_tbl_t[LAST_CALLBACK_ID];

typedef struct {
    uint32_t id;
    callback_tbl_t cl_tbl;  
} proto_impl_t;

static proto_impl_t impl[MAX_NOF_IMPLS] = { 0 };

callback_tbl_t *impl_get_callbacks ( uint32_t impl_id ) {

    for ( uint32_t i = 0; i < MAX_NOF_IMPLS; i++ ) {
        if ( impl[i].id == impl_id ) {
            return &impl[i].cl_tbl;
        }
    }

    int32_t ( *(*f)[32] ) (uint32_t) = NULL;    /* Это я уже сейчас добавил, проверить ругнется ли компилятор. Не ругается. */

    return f;
}
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jan 30 2018, 10:38
Сообщение #100


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(dxp @ Jan 30 2018, 12:08) *
char (*(*func(void))[3])(void);

да, не указатель (проглядел скобки справа), но это и не функция. sm.gif Строго говоря, func - есть имя функции, которое семантически является её адресом, т.е. технически это указатель. Всё выражение да, не указатель, но, строго, и не функция.

Технически любое имя функции - это есть указатель. Даже
Код
void f1(void);

Согласно Вашей логике, f1 - не функция? Стандартописатели из комитета ANSI C ошиблись с терминологией? rolleyes.gif
Все выражение, все-таки - функция... Вернее, ее прототип.
Код
char (*(*func(void))[3])(void)
{
  ...
}

Технически, синтаксически, логически, семантически (что там еще?) - это именно функция. Я могу ее вызвать, потому что это функция. Я не могу присвоить func ничего, потму что это не указатель, а идентификатор, связанный с выделенным участком кода.

Вот небольшой пример
Код
// ôóíêöèÿ, âîçâðàùàþùàÿ óêàçàòåëü íà ìàññèâ óêàçàòåëåé íà ôóíêöèè, âîçâðàùàþùèå char

#include <stdio.h>

char func1(void) {printf("I am func1\n"); return 1;}
char func2(void) {printf("I am func2\n"); return 2;}
char func3(void) {printf("I am func3\n"); return 3;}

char (*MassFunc[3])(void) = {func1, func2, func3};

char (*(*func(void))[3])(void)
{
    return &MassFunc;
}

int main(void)
{
    int *pFunc = (int *)func();
    
    for(int i = 0; i < 3; ++i)
       (*(char (*)())pFunc[i])(); // в С указатели на функции не индексируются, поэтому используется промежуточный указатель на int
    
    while(1);
}



Важное замечание №1: если все-таки придется использовать какую-то гибкую схему вызовов - лучше, как и было озвучено Quasar, через typedef.
Важное замечание №2: не пишите так никогда (как в примере выше у меня). Это всего лишь пример, но никак не побуждение к действиям. Если и хочется сделать что-то гибко и структурно - лучше тщательно продумать концепцию кода и оформить с typedef-ами (иначе Вас потом будут проклинать biggrin.gif ).
Go to the top of the page
 
+Quote Post

8 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 21:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.02771 секунд с 7
ELECTRONIX ©2004-2016