Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Библиотеки для STM32
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3, 4, 5, 6, 7, 8
Forger
Цитата(Kabdim @ Apr 4 2017, 14:25) *
Вы про C99 не слышали?

Обратите внимание в какой теме и в каком разделе мы все это пишем ... wink.gif
C-исходник в подавляющем числом компиляторов под МК не поддерживает С99, поэтому мы не можем где ни попади объявлять локальные переменные.
И, честно говоря, не вижу смысла строчить в С или С99, когда есть плюсы. Но это - по-ходу уже другая тема )))

Цитата
Вы уверены что это можно назвать хорошим стилем? sm.gif
Если цикл занимает всего пару строк, а не 10 страниц кода, то никакого криминала в этом не вижу ))
Само тело цикла удобно использовать для ограничения зоны видимости его итератора, главное - давать осмысленные имена, чтобы они не вступали в конфликт с именами других объектов, фигурирующих в теле цикла.

Цитата
Это называется plain old data (POD)

Да, это именно оно ))
По сути, лишь для этого я и использую слово struct, так сразу видно в коде, о чем идет речь.
А все остальные сущности - class. Даже для примитивных, т. е. не имеющих своих методов (но в будущем, возможно, будут).

Цитата(juvf @ Apr 4 2017, 15:33) *
рефакторинг ещё ни кто не отменял.

Автоматизация "мартышкиного" труда еще не отменяет самого факт такого труда )))
К тому же даже в данный момент далеко не все среды (тоже обратите на тему и раздел где мы сидим) поддерживают такие вещи по ВСЕМУ проекту.
Речь в данном случае не про внешние редакторы, а целиком про среды проектирования (Keil, Eclipse, Crossworks и др).
kostyan
Цитата(Forger @ Apr 4 2017, 18:05) *
Автоматизация "мартышкиного" труда еще не отменяет самого факт такого труда )))
К тому же даже в данный момент далеко не все среды (тоже обратите на тему и раздел где мы сидим) поддерживают такие вещи по ВСЕМУ проекту.
Речь в данном случае не про внешние редакторы, а целиком про среды проектирования (Keil, Eclipse, Crossworks и др).


В Eclipse это Alt + Shift + R с древних времен и да ПО ВСЕМУ проекту...
juvf
Цитата(Forger @ Apr 4 2017, 18:05) *
тоже обратите на тему и раздел где мы сидим
так то я ТС ))) и тема не про стиль кода, а про библиотеки для стм32 ))

Цитата
Речь в данном случае не про внешние редакторы, а целиком про среды проектирования (Keil, Eclipse, Crossworks и др).
в Eclipse этo Alt+Shift+R. На базе эклипса много сред (кокос, CCS, NIOS-IDE). Вообще эклипс - рулит. Остальные среды .... но это уже новый холивар )))
Да даже в IAR-e, со своим редактором, застрявшим в 90-х годах, можно сделать поиск с заменой в пару кликов. Ни какого мартышкиного труда ))

ps что ещё вкусного в эклипсе - автоматическое форматирование кода. берёшь чужой код... там фигурные скобки не так как у меня стоят, отступы не те, пробелы не так, выравнивание schitch/case/break по другому. жамкаешь ctrl+shift+F - весь файл перефарматируется в мой стиль (только естественно стиль должен быть настроен и/или подключен. я один раз стиль настроил и всегда его подключаю, во всех эклипсонаследовательных ИДЭ)
Forger
Цитата(kostyan @ Apr 5 2017, 07:01) *
В Eclipse это Alt + Shift + R с древних времен и да ПО ВСЕМУ проекту...

"пук в лужу" с моей стороны - не сижу в эклипсе (пора исправлять это ...), привел его в пример фактически наугад ))


Цитата(juvf @ Apr 5 2017, 07:13) *
Ни какого мартышкиного труда )) ..... что ещё вкусного в эклипсе - автоматическое форматирование кода. берёшь чужой код...

Под мартышкиным трудом понимаю переделывание своего кода, а не чужого.
Alechek
Цитата(juvf @ Apr 4 2017, 17:33) *
я тоже не поддерживаю в имени переменной её тип (как например в том же гугл сайл)

А ни разу не сталкивались, когда при очередной модификации кода (через 10*N месяцев) в 16 бит переменной (поле структуры) нечаянно пытались освоить биты >16?
Forger
Цитата(Alechek @ Apr 6 2017, 07:52) *
А ни разу не сталкивались, когда при очередной модификации кода (через 10*N месяцев) в 16 бит переменной (поле структуры) нечаянно пытались освоить биты >16?

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

Кроме шуток, существует весьма полезная вещь - sizeof, или для более продвинутых: (1 << ( sizeof(...)*8 ) ) - 1
juvf
Цитата(Alechek @ Apr 6 2017, 09:52) *
А ни разу не сталкивались, когда при очередной модификации кода (через 10*N месяцев) в 16 бит переменной (поле структуры) нечаянно пытались освоить биты >16?

нет, ни разу. никогда к битам не обращяюсь напрямую типа a |= (1 << 24); Только через дефайны. a |= STATE_A;
хидере пишу что-то типа такого
Код
#define STATE_A (1<<0)
#define STATE_B (1<<1)
#define STATE_C (1<<2)
...
#define STATE_x (1<<15)

uint16_t state = STATE_C | STATE_B | STATE_F;

определяя новый дефайн всегда помню(проверяю) про размерность переменной. это раз....

и второй подход - это битовые поля. например так
Код
typedef union
{
    struct
    {
        uint16_t enterTrip         :1; //
        uint16_t exitTrip         :1;
        uint16_t printTrip         :1;
        uint16_t printCheck1     :1;
        uint16_t printCheck2     :1; //
                uint16_t printCheck3     :1; //
        uint16_t printTest         :1;
        uint16_t setTime         :1;
        uint16_t getTime         :1;
        uint16_t setLine         :1;
        uint16_t getLine         :1;
        uint16_t setColor    :1;
        uint16_t getColor    :1;

        uint16_t rezerv :3;
                //uint16_t rezerv2 :16;//для выравнивания в 32 можно раскоментировать
    } flags;
    uint16_t word;//если раскоментирован флаг rezerv2, то закоментировать
        //uint32_t word;//если раскоментирован флаг rezerv2, то раскоментировать
} FlagsKL;
....
FlagsKL flagsKL;
flagsKl.word = 0;//сброс всех бит в ноль
flagsKL.flags.printCheck2 = 1;//установить бит 4 в 16-ти битной переменной
при таком написании вообще пофиг в каком месте биты стоят.... printCheck2 - 4-ый или 8-ой. при таком подходе... не возможно ошибиться и вылезти за размер 16 бит.

бывало такое
Код
uint8_t asd;
....
asd = 300;
но это быстро ловиться... если это поле структыры, то компилятор подсвечивает подсказку - как это поле структыры обявлено, тип этой переменной
Forger
Цитата(juvf @ Apr 6 2017, 08:24) *
и второй подход - это битовые поля

А, если еще компилятор поддерживает безымянные объединения, то получается полный феньшуй:

Код
typedef struct // Frame
{
    struct // Supported only 11-bit ID (CAN 2.0A)
    {
        UNSIGNED1 nodeId : 7;
        UNSIGNED1 functionCode : 4;
    } cobId;

    bool        isRemoteTransmitionRequest;

    UNSIGNED8    dataLength;
    union
    {
        UNSIGNED8    dataPayload08[8];
        UNSIGNED16    dataPayload16[4];
        UNSIGNED32    dataPayload32[2];
        UNSIGNED64    dataPayload64;
    };
} Frame;


nodeId при присвоении проверяется на граничные значения внутри соотв. метода соотв. класса, т.е. в одном месте, а не размазаны по всему коду ...
functionCode вообще может принимать лишь фиксированные значения:

Код
// Peer-to-Peer objects of the CANopen Predefined Master/Slave Connection Set
const struct
{
    UNSIGNED8 nodeControl;
    UNSIGNED8 emergencyAndSynchronize;
    UNSIGNED8 timeStamp;
    UNSIGNED8 TPDO1;
    UNSIGNED8 RPDO1;
    UNSIGNED8 TPDO2;
    UNSIGNED8 RPDO2;
    UNSIGNED8 TPDO3;
    UNSIGNED8 RPDO3;
    UNSIGNED8 TPDO4;
    UNSIGNED8 RPDO4;
    UNSIGNED8 TSDO;
    UNSIGNED8 RSDO;
    UNSIGNED8 errorControl;
} peerToPeerObject = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14};


вот так используется:
Код
    
void CANopenSlave::operator << (Frame & rxFrame)
{
    // Broadcast Message
    if (rxFrame.cobId.nodeId == 0)
    {
        if (rxFrame.cobId.functionCode == peerToPeerObject.nodeControl)
        {
            processNodeControl(rxFrame);
            ......




зы. это коду выше более 5 лет (если не больше), но по-прежнему легко читается...
Alechek
Цитата(juvf @ Apr 6 2017, 10:24) *
нет, ни разу. никогда к битам не обращяюсь напрямую типа a |= (1 << 24); Только через дефайны. a |= STATE_A;


Счастливчик.
Только увы, биты можно освоить и простым сложением величин... А потом долго не втыкать, почему же с = a+b не работает...Или с = a - b, если b > a...
А все было бы гораздо прозрачней, если usC = iA - iB

Еще интересней случаи, когда
Data = N;
вместо
*Data = N;

а с
*pData = N;
сделать ошибку куда сложней.
Forger
Цитата(Alechek @ Apr 6 2017, 20:19) *
А все было бы гораздо прозрачней, если usC = iA - iB

© "Ежики кололись, но все равно ели кактус" sm.gif

Цитата
*pData = N;
сделать ошибку куда сложней.


Только что попробовал такую конструкцию:

Код
int value = 10;
int * pointer;
....
pointer = value;

Тут же получил от компилятора (keil) по носу:

error: #513: a value of type "int" cannot be assigned to an entity of type "int *"

Но это проглатывает:
Код
int * pointer;
pointer = 0;

Хотя я никогда так не пишу, а использую вместо нуля эту штуку (ее нет в С++):
Код
#undef NULL
#define    NULL ((void*)0)
.....
pointer = NULL;


Тогда при попытке присвоить обычной переменной эту NULL:
Код
int value;
....
value = NULL;

получим от компилятор опять щелчок по носу:
error: #513: a value of type "void *" cannot be assigned to an entity of type "int"





зы. Честно, прям дикости какие-то вы тут пишите wacko.gif

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

Хотя раньше указатели я именовал, но не шифровками типа - "p" или "ptr", а с полностью - с припиской "Pointer" в конце названия.
В данный момент указателей практически нет, кроме редких случаем в низкоуровневых драйверах да и то крайне редко, всегда стараюсь избегать указатели в коде.
Это несложно, т. к. пишу под плюсами, поэтому использую ссылки, а не указатели.
Так безопаснее да и код читается лучше, т.к. нет "->".
juvf
Цитата(Alechek @ Apr 6 2017, 22:19) *
Еще интересней случаи, когда
Data = N;
вместо
*Data = N;

Ха..... Да и без ругони компилятра не допускаю такие ошибки.... Не знаю почему... Такое руки сами не напишут... Это даже детской ошибкой не назвать.... )))
ps а ещё есть ссылки. они более защищены, чем указатель.

Цитата
Честно, прям дикости какие-то вы тут пишите
+100
Цитата
Только увы, биты можно освоить и простым сложением величин...
какие биты у величин? Биты - это флаги. Вам нужно проверить 3, 6 и 18 флаг по "И", проверяйте if(a & ((1<<3) | (1<<6) | (1<<18)){}
по "ИЛИ" - проверяйте if(a | ((1<<3) | (1<<6) | (1<<18)){} Грамозко, непонятно, требует комента? сделайте дефайн
#define IS_PRESENT_ALL ((1<<3) | (1<<6) | (1<<18))
if(a | IS_PRESENT_ALL){}
а также
a |= (1<<7);//выставить 7-ой бит
a &= ~(1<<19);//сбросить 19-ый бит
Какое у битов сложение? Если нужно переменную в 2 и более бита - используйте битовые поля, обращайтесь к ним как к простым переменным.
Сергей Борщ
QUOTE (Forger @ Apr 6 2017, 23:21) *
(ее нет в С++):
Там "из коробки" специально для этого есть nullptr.
Alechek
Forger, juvf, вы сильно зацикливаетесь на своем коде. Я рад за вас, что вы сразу пишете идеальный код.
Не у всех так получается. А люди еще бывает работают в команде. А еще бывает, люди пишут код, который потом будут массово пользовать другие (как те же библиотеки stm32).
Forger
Цитата(Сергей Борщ @ Apr 7 2017, 08:38) *
Там "из коробки" специально для этого есть nullptr.

Это относится лишь к компиляторам, которые поддерживают C++11.

В ARM-компиляторе (Keil) есть частичная поддержка C++11, nullptr в его редакторе подкрашивается, это удобно ))
"Из коробки" не заработает, нужно обязательно включать опцию компилятора "--cpp11".

Но обязательно возьму на вооружение! Спасибо biggrin.gif


Цитата(Alechek @ Apr 7 2017, 09:32) *
Не у всех так получается.
Неправда - у всех это получается, ничего тут сложного нет.
А дело, возможно, в другом - не все хотят учится и переучиваться wink.gif

Цитата
А люди еще бывает работают в команде.

Тем более!
Логичнее приучить всю команду сразу писать правильно, создав свод правил или использовать готовые, как тут уже писали,.
Ведь на то она и команда, чтобы следовать единым и удобным для всех правилам, а не писать каждый как хочет!
Придется все же выбрать: общие правила (законы) или "ежики кололись, но продолжали есть кактус" (повторяюсь) smile3046.gif

Цитата
А еще бывает, люди пишут код, который потом будут массово пользовать другие (как те же библиотеки stm32).

Какое странное оправдание ..

.
Alechek
Цитата(Forger @ Apr 7 2017, 11:50) *
Какое странное оправдание ...

Ладно, последняя попытка cool.gif
Не все пишут на С++ и С++11
Те же библиотеки stm32 написаны на С. А ему пофиг на
Код
int value = 10;
int * pointer;
....
pointer = value;
Forger
Цитата(Alechek @ Apr 7 2017, 10:18) *
Не все пишут на С++ и С++11

Это тут ни при чем.
Я использую C-библиотеки stm32 в C++. Неразрешимых проблем не было.

Цитата
Те же библиотеки stm32 написаны на С. А ему пофиг на
Код
int value = 10;
int * pointer;
....
pointer = value;

Так смените свой компилятор на нормальный, которому это не пофиг!
Или покопайтесь в настройках компилятора, чтобы он ругался на такие вещи хотя бы warning-ми.
Честно слово, как дети малые ...

зы. Скажите, при сборке всего проекта вы сразу добиваетесь, чтобы не было ни одного warning-а или откладываете это на потом? wink.gif
juvf
Цитата(Alechek @ Apr 7 2017, 11:32) *
Forger, juvf, вы сильно зацикливаетесь на своем коде. Я рад за вас, что вы сразу пишете идеальный код.
Не у всех так получается. А люди еще бывает работают в команде. А еще бывает, люди пишут код, который потом будут массово пользовать другие (как те же библиотеки stm32).
Я не зациклен. Я предложил свой стаил. Он не единственно верный. Гугл стайл мне не понравился... тип переменной в имя сувать - тоже мне не по вкусу. раньше вроде так писали int *pName; Сечас..... посмотрите другие стайлы.... мой стаил гавно? посмотрите гугл, Qt,.... посмотрите исходники Linux - это пуре СИ.
Цитата
Те же библиотеки stm32 написаны на С. А ему пофиг на
иаровски СИШНЫЙ компилятр не скомпилировал такое, ругнулся
Код
int *i;
i = 200;

gcc тоже такое не проглотит. Не нужно нормальный компилятор. мне кажется не один компилятор такое не проглотит. Или я ошибаюсь? Какой компиллер такое проглитит?

Я не пишу идеальный код сразу и правильно.... но мне эти р не нужны. Более того, они мне мешают. Если вам с ними комфортно, с ними меньше ошибок и быстрее пишется - ни кто вам не запрещяет ставить р.
Obam
Цитата
иаровски СИШНЫЙ компилятр не скомпилировал такое, ругнулся
Код
int *i;
i = 200;

Отцы, вам самим не смешно такие примеры приводить?

Позвольте зацитировать первооснователей (K&R):
int х = 1, у = 2, z[10];
int *ip; /* ip - указатель на int */
ip = &x; /* теперь ip указывает на х */
y = *ip; /* у теперь равен 1 */
*ip =0; /* х теперь равен 0 */

выделено мной.
juvf
Цитата(Obam @ Apr 7 2017, 14:31) *
Отцы, вам самим не смешно такие примеры приводить?
не в тему сказал. войди в тему, начни читать с 109 поста. вместе посмеёмся.
Forger
Цитата(Obam @ Apr 7 2017, 12:31) *
Позвольте зацитировать первооснователей (K&R):
int х = 1, у = 2, z[10];
int *ip; /* ip - указатель на int */
ip = &x; /* теперь ip указывает на х */
y = *ip; /* у теперь равен 1 */
*ip =0; /* х теперь равен 0 */

выделено мной.

Такую "кашу" из букв даже при желании сочинить трудно, определенно нужен "талант"! sm.gif
Obam
Из #109
Цитата
…биты можно освоить и простым сложением величин...

Пожалуй, всплакну. Не прёт меня логические операции арифметическими реализовывать.


Цитата(Forger @ Apr 7 2017, 13:38) *
Такую "кашу" из букв даже при желании сочинить трудно, определенно нужен "талант"! sm.gif

Никакой отсебятины. Brian Kernighan and Dennis Ritchie. Pure. (; Скриншот, надеюсь, не заставите представлять…
Forger
Цитата(Obam @ Apr 7 2017, 12:48) *
Никакой отсебятины. Brian Kernighan and Dennis Ritchie. Pure. (;

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

С таким же успехом можно сравнивать паровую машину с современной )))
Obam
Он - старенький; Риччи 6 лет как помер.
Так ведь с тех "дремучих времён" текст в книжке можно ж было и поправить. Не раз.

Нормально на "Электронике-60" было, желание надо было просто иметь…

"… да и программы тогда были очень простые в сравнении с современными..." ой простыыыыми, что целый Unix накатали (;
Forger
Цитата(Obam @ Apr 7 2017, 13:02) *
Так ведь с тех "дремучих времён" текст в книжке можно ж было и поправить. Не раз.

Не было этой темы и даже этого форума, поэтому не знали люди, как можно жисть упростить ))
juvf
Цитата(Obam @ Apr 7 2017, 14:48) *
Никакой отсебятины. Brian Kernighan and Dennis Ritchie. Pure. (; Скриншот, надеюсь, не заставите представлять…
нормальная каша. на пальцах разжёвано что такое адрес и указатель. всё понятно. Вот только там нет рекомендаций про стиль кода. А для учебника Си, для 5 строк кода, особенно для раздела указателей (и ссылок в с++), наверно даже нужно в имя переменной втолкнуть тип.
Alechek
Цитата(Forger @ Apr 7 2017, 12:22) *
Так смените свой компилятор на нормальный, которому это не пофиг!
Или покопайтесь в настройках компилятора, чтобы он ругался на такие вещи хотя бы warning-ми.
Честно слово, как дети малые ...

IAR

Как заставить ругаться на все неправильные варианты?
Цитата
void f(int * InData)
{
int * WorkData;

memcpy(WorkData, InData, 10);
memcpy(&WorkData, InData, 10);
memcpy(&WorkData, &InData, 10);
memcpy(WorkData, &InData, 10);
}


Цитата(Forger @ Apr 7 2017, 12:22) *
зы. Скажите, при сборке всего проекта вы сразу добиваетесь, чтобы не было ни одного warning-а или откладываете это на потом? wink.gif

Таких
Код
Warning[Pe550]: variable "i" was set but never used

бывает много. На остальные всегда смотрится.

Obam
Шаг за шагом, по каждому warning-у, а можно ещё и remarks

Workspace -> Options -> C/C++ Compiler -> Diagnostics -> птички "Enable remarks", "Treat all warnings as errors"
Workspace -> Options -> Linker -> то ж самое
меню Tools -> Options -> Messages… -> Show build messages -> All
Forger
Цитата(Alechek @ Apr 7 2017, 13:38) *
IAR

Как заставить ругаться на все неправильные варианты?

Во-первых, не писать такой код, где фигурируют магические числа (кроме числа ноль).
Заменяйте ваши ноунейм указатели указателями на структуры, дав им логичные имена.
Используйте встроенный оператор sizeof, чтобы уйти от магических цифр.
Учтите, что sizeof указателя будет давать размер указателя, но не данных, куда он указывает. Поэтому в sizeof() ставьте тип данных, а не сам объект.
Используйте приведение типов, это вносит хотя бы дополнительную полезную информацию в и без того куцый и корявый код ))
Смело используйте typedef, создавая свои осмысленные типы. Это приучает к порядку в коде.
Указатели используйте как можно реже и старайтесь ограничивать область их видимости и применения хотя бы в пределах одного файла.
Не нужно раньше времени заморачиваться на экономии ОЗУ или FLASH, в современных МК это не проблема.

В вашем примере я бы отказался от memcpy и использовал копирование в самописном цикле. Это будет явно и избавит от детских ошибок.

Если пишите под плюсами, пользуйтесь ссылками, а указателей быть не должно.

За глобальные указатели - расстрел на месте!

Цитата
На остальные всегда смотрится.

На них вообще не приходится смотреть, если их вообще нет, т.е. "Warnings: 0". По-моему, это проще ))

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

Короче, мой вам совет - читайте книжки опытных программеров (здесь они озвучивались), двигайтесь вперед и все получится, БЕЗ КОСТЫЛЕЙ wink.gif
Alechek
Цитата(Forger @ Apr 7 2017, 16:06) *
Заменяйте ваши ноунейм указатели указателями на структуры, дав им логичные имена.
Используйте встроенный оператор sizeof, чтобы уйти от магических цифр.
Смело используйте typedef, создавая свои осмысленные типы. Это приучает к порядку в коде.


И чем эти советы помогут в этом?
Цитата
typedef struct stream_data {
uint32_t Header;
uint8_t Data[10];
} STREAMDATA, *LPSTREADMATA;

void f(LPSTREADMATA InData)
{
char WorkData[120];

memcpy( WorkData, InData, sizeof(*WorkData));
memcpy(&WorkData, InData, sizeof( WorkData));
memcpy(&WorkData, &InData, sizeof(*WorkData));
memcpy( WorkData, &InData, sizeof( WorkData));
}

не использовать memcpy?

Цитата(Forger @ Apr 7 2017, 16:06) *
Короче, мой вам совет - читайте книжки опытных программеров (здесь они озвучивались), двигайтесь вперед и все получится, БЕЗ КОСТЫЛЕЙ wink.gif

Если честно, то сымый лучший код, который я видел - это исходники WINCE. прочее и рядом не стояло. особенно озвучивамый тут linux.
Сергей Борщ
QUOTE (Alechek @ Apr 7 2017, 13:38) *
Как заставить ругаться на все неправильные варианты?
Все эти варианты синтаксически правильные. Заставлять надо программиста, чтобы учил язык и писал понятный код.
Alechek
А в чем memcpy непонятный?

я за то, что
Код
memcpy(pWorkData, pInData, sizeof(*pWorkData));

, снабженный комментарием, ЗАЧЕМ мы это делаем - самый понтяный вариант.
juvf
Цитата
Код
memcpy(WorkData, InData, 10);
это выстрел себе в ногу.
компилятор тут не поможет. стиль кода и имена переменных тоже. к типу указатель viod вроде как си неявно преобразует без ограничений.

Код
я бы отказался от memcpy и использовал копирование в самописном цикле.
memcpy - можно реализовать разными способами.... можно опуститься на уровень ассемблера и написать ассемлерный код копипаста. memcpy - реализован самым оптимальным способом. поэтому не нужно изобретать велосипед свой цикл копирования, а использовать memcpy.

Код
void f(LPSTREADMATA InData)
{
char WorkData[120];

memcpy( WorkData, InData, sizeof(*WorkData));
memcpy(&WorkData, InData, sizeof( WorkData));
memcpy(&WorkData, &InData, sizeof(*WorkData));
memcpy( WorkData, &InData, sizeof( WorkData));
}
что за бред? а если WorkData, InData вы назавете pWorkData, pInData - это сильно поможет?

Код
void f(LPSTREADMATA InData)
Глядя на это, я не понимаю что передается в функцию. я не люблю когда тайпдефят указатели. я бы определил функцию как
Код
void f(STREAMDATA *InData)
-сразу видно, что передается указатель.

Цитата
Если пишите под плюсами, пользуйтесь ссылками, а указателей быть не должно.
сплошь и рядом указатели. Ссылка должна быть там, где она должна быть, а указатель - где указатель. Eсли с++, то там ооп. а ооп - это сплошь и рядом указатели... всякие createWindow(), getSender()... паттерны - тоже указатели. обращение к регистрам перефирии процессора - опять указатели. Куда без них?
Forger
Цитата
memcpy - можно реализовать разными способами.... можно опуститься на уровень ассемблера и написать ассемлерный код копипаста. memcpy - реализован самым оптимальным способом. поэтому не нужно изобретать велосипед свой цикл копирования, а использовать memcpy.

Как видим, некоторым программистом memcpy - зло. Потому нет беды, если будет обычный цикл, за то нет детских граблей.

Цитата
сплошь и рядом указатели. Ссылка должна быть там, где она должна быть, а указатель - где указатель. Eсли с++, то там ооп. а ооп - это сплошь и рядом указатели... всякие createWindow(), getSender()... паттерны - тоже указатели. обращение к регистрам перефирии процессора - опять указатели. Куда без них?

Обратите внимание, кому я обращал тот пост - профи сами разберутся что к чему, а новичку дай высокотехнологичный инструмент, так руки себе отпилит ...
Кто обращается к регистрам напрямую, те никогда не наступают на грабли с memcpy wink.gif
Alechek
Цитата(juvf @ Apr 7 2017, 16:55) *
Код
memcpy( WorkData, InData, sizeof(*WorkData));
memcpy( WorkData, &InData, sizeof( WorkData));
}
что за бред? а если WorkData, InData вы назавете pWorkData, pInData - это сильно поможет?

void f(LPSTREADMATA InData)
Глядя на это, я не понимаю что передается в функцию. я не люблю когда тайпдефят указатели. я бы определил функцию как
void f(STREAMDATA *InData)
-сразу видно, что передается указатель.

Вы противоречите самому себе sm.gif

Цитата(juvf @ Apr 7 2017, 16:55) *
memcpy - можно реализовать разными способами.... можно опуститься на уровень ассемблера и написать ассемлерный код копипаста. memcpy - реализован самым оптимальным способом. поэтому не нужно изобретать велосипед свой цикл копирования, а использовать memcpy.

Скорее всего, и имелось ввиду использовать вместо memcpy присвоение неких структур через указатели на них.
вот, только массивы в структурах могут быть открытими... (в С)
Obam
Цитата(Forger @ Apr 7 2017, 16:24) *
Кто обращается к регистрам напрямую, те никогда не наступают на грабли с memcpy wink.gif

Назад на пальму к корням в ассмы!!! Шутка…
Шаманъ
Цитата(Alechek @ Apr 7 2017, 10:18) *
Ладно, последняя попытка cool.gif
Не все пишут на С++ и С++11
Те же библиотеки stm32 написаны на С. А ему пофиг на
Код
int value = 10;
int * pointer;
....
pointer = value;


А че, редакторы нормальные отменили? У меня только мышь подводишь к переменной и сразу видно тип переменной, ошибиться нереально.

P.S. ИМХО, логичные и информативные названия переменных ничуть не хуже венгерской нотации работают, еще и код более "читабельный" получается.
Alechek
Цитата(Шаманъ @ Apr 7 2017, 17:48) *
А че, редакторы нормальные отменили? У меня только мышь подводишь к переменной и сразу видно тип переменной, ошибиться нереально.

Подгружать весь проект вместо того, чтобы в блокноте бегло глянуть на кусок кода? (когда тип определен где-то в дебрях кучи *.h)

И да, тут уже был ответ:
Цитата(Forger @ Apr 4 2017, 18:05) *
Автоматизация "мартышкиного" труда еще не отменяет самого факт такого труда )))
К тому же даже в данный момент далеко не все среды (тоже обратите на тему и раздел где мы сидим) поддерживают такие вещи.....
Речь в данном случае не про внешние редакторы, а целиком про среды проектирования (Keil, Eclipse, Crossworks и др).
juvf
Цитата(Obam @ Apr 7 2017, 17:42) *
Назад на пальму к корням в ассмы!!! Шутка…

не куда не назад. пока единственный путь.

2Alechek Где я противоречу? где я в имеми переменой в своем примере вставил хоть что-то от типа переменной?

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

void f(LPSTREADMATA pInData) - встретив такую запись не понятно что передается? вызывается ли копирющий контруктор, делается ли копия переменной/структуры типа LPSTREADMATA. вам необходимо в имя переменной воткнуть pInData, иначе не видно, что передается указатель. вам, чтоб не запутаться, нужны наверно и в имя типа вставка LPSTREADMATA, и в имя переменной вставка pInData.

я не тайпдефю указатели. не делаю LPSTREADMATA и т.п. типы. я пишу
void f(STREADMATA *inData) - по такой записи я сразу вижу, что передается указатель, и более того, я вижу, что данные по указателю inData внутри функции будут изменены. т.е. функция f() меняет структуру, указатель на которую передается в качестве аргумента, внешняя структура будет изменена. а вашем стиле, без дополнительных вставок в имена типа и переменной, не понятно... будет меняться структура или нет, т.е. не понятно передается указатель или копия структуры будет создана на стеке.
Шаманъ
Цитата(Alechek @ Apr 7 2017, 16:06) *
Подгружать весь проект вместо того, чтобы в блокноте бегло глянуть на кусок кода? (когда тип определен где-то в дебрях кучи *.h)

Используемый нынче у меня редактор умеет более-менее успешно вытягивать и без проектов такие штуки из "дебрей кучи *.h" sm.gif

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


Цитата(juvf @ Apr 7 2017, 16:17) *
я не тайпдефю указатели. не делаю LPSTREADMATA и т.п. типы. я пишу
void f(STREADMATA *inData)

Кстати да, специальные типы с указателями это зло. Как-то с libpng возился, a там любители typedefов наплодили и указателей, и указателей на указатели - жесть...
juvf
оффтоп по поводу переделки тайпдефов.... тут говнолидер - это Texas Instuments.... со своею TI-RTOS и SPL.

их код создание таска
Цитата
Void heartBeatFxn(UArg arg0, UArg arg1)
{
}

хорошо, что идэ у них на эклипсе.... что такое Void? ctrl+ЛКМ улетаем в какой-то хидер
Код
#define Void xdc_Void
ещё раз ctrl+ЛКМ, ултетаем в
Код
#define xdc_Void        void

ну да ладно.... Void интуитивно понятно что это void. А вот что такое UArg arg0? ctrl+ЛКМ (ещё раз спсибо эклипсу, чтоб я без него делал?) улетаем в хидер
Код
typedef xdc_UArg        UArg;

далее ctrl+ЛКМ - полёт по хидерам...
Код
typedef uintptr_t       xdc_UArg;
-
uintptr_t вроде всё понятно.... u - значит unsigned, int - это int, ptr - т.е. pointer, т.е. указатель, _t - тип. делаем контрольный ctrl+ЛКМ
Код
typedef unsigned int uintptr_t;


NO COMMENT!!!

а вы говорите заглянул по быстрому в блокнот ))))


Шаманъ
Цитата(juvf @ Apr 7 2017, 17:01) *
тут говнолидер - это Texas Instuments.... со своею TI-RTOS и SPL.

Оо! Зря я наехал на libpng laughing.gif
Alechek
Цитата(juvf @ Apr 7 2017, 18:17) *
2Alechek Где я противоречу? где я в имеми переменой в своем примере вставил хоть что-то от типа переменной?

Вам, чтобы видеть лучше тип, надо *, но при этом вы против некоторго символа в другом месте.
Хотя и то и другое способствует повышению скорости писания кода одновременно с уменьшеним вероятности ошибки.

Цитата(Шаманъ @ Apr 7 2017, 18:54) *
Хоть в общем случае вопрос скорее не про инструменты, а про написание понятного и правильного кода, а также про организацию работ в целом - согласитесь, что "в блокноте бегло глянуть и внести изменения в проект подробности которого уже крепко забыты" это самый верный способ создания подобных проблем.

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

Цитата(juvf @ Apr 7 2017, 19:01) *
Код
Void heartBeatFxn(UArg arg0, UArg arg1)

а вы говорите заглянул по быстрому в блокнот ))))


вот и я о том же.
При:
Код
Void heartBeatFxn(UArg p_arg0, UArg p_arg1)

сразу видно. что речь идет об указателях. И не важно, как там дальше оно раскрывается.

Forger
Цитата(Alechek @ Apr 7 2017, 15:38) *
Скорее всего, и имелось ввиду использовать вместо memcpy присвоение неких структур через указатели на них.

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

Цитата
вот, только массивы в структурах могут быть открытими... (в С)

Дык, они открыты по-умолчанию и в С++ ))

В плюсах этот кусок делается через ссылку на некий класс, которые в своих недрах содержатся нужные данные.
А через соотв. метод этого же класса "достучаться" до его данных.
Шаманъ
Цитата(Alechek @ Apr 7 2017, 17:17) *
сразу видно. что речь идет об указателях. И не важно, как там дальше оно раскрывается.

Та не нифига там не видно. За очень редким исключением указатель лучше не заталкивать в тип, а каждый раз объявлять явно - намного понятнее, ибо буква р это просто символ, который может быть в разных местах по разным причинам, а вот * в этом месте это только указатель. Т.е. в первом случае надо еще подумать и быть намного более внимательному, а во втором видно сразу.
Цитата
Иногда приходится...

Я не говорю по какие-то исключения - бывает всякое, я про нормальную работу.
juvf
Цитата(Alechek @ Apr 7 2017, 19:17) *
Код
Void heartBeatFxn(UArg p_arg0, UArg p_arg1)

сразу видно. что речь идет об указателях. И не важно, как там дальше оно раскрывается.
мне не видно.... пусть я слеп. Но вам видно?! УКАЗАТЕЛИ!? Одну ногу отстрелили! ))) я же раскрыл все тайпдефы. это не указатели, это unsigned int
Alechek
Цитата(juvf @ Apr 7 2017, 19:40) *
мне не видно.... пусть я слеп. Но вам видно?! УКАЗАТЕЛИ!? Одну ногу отстрелили! ))) я же раскрыл все тайпдефы. это не указатели, это unsigned int

Мне видно, что это указатель c конкретным размером в 32 бит:
Код
typedef uintptr_t       xdc_UArg;


Кстати, такое есть и в WINDOWS:
Цитата
LONG_PTR A signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic.

This type is declared in BaseTsd.h as follows:
C++

#if defined(_WIN64)
typedef __int64 LONG_PTR;
#else
typedef long LONG_PTR;
#endif
AHTOXA
Цитата(juvf @ Apr 7 2017, 19:01) *
uintptr_t вроде всё понятно.... u - значит unsigned, int - это int, ptr - т.е. pointer, т.е. указатель, _t - тип. делаем контрольный ctrl+ЛКМ
Код
typedef unsigned int uintptr_t;


NO COMMENT!!!

Отличный пример того, как буковки в префиксах имён могут быть неверно истолкованы.
(Но вообще-то uintptr_t - это стандартный тип (из stdint.h), и его название означает "беззнаковое целое, размер которого достаточен для хранения указателя").

Цитата(Alechek @ Apr 7 2017, 19:17) *
При:
Код
Void heartBeatFxn(UArg p_arg0, UArg p_arg1)

сразу видно. что речь идет об указателях. И не важно, как там дальше оно раскрывается.

Совершенно не видно. Может, p_ - это от слова "parameter". А может, просто автор любит писать p_. Или имя осталось от прошлой версии интерфейса функции, когда этот параметр был указателем, а в нынешней версии он уже давно не указатель. В любом случае придётся проверять.
Ещё один момент. Вы же в своих проектах используете сторонние библиотеки? И наверняка среди них есть такие, которые не придерживаются привычного вам соглашения о префиксах. Так что вам, с вашим подходом придётся всё время отслеживать, в каком вы сейчас коде - в своём (с привычными вам префиксами имён) или в стороннем (который, не использует таких соглашений).
Поэтому сейчас есть тенденция отказа от таких префиксов.
juvf
Цитата(Alechek @ Apr 7 2017, 19:55) *
Мне видно, что это указатель c конкретным размером в 32 бит:
Код
typedef uintptr_t       xdc_UArg;
Выстрел!!! Вторую ногу отстрелили. в си/с++ нет типа uintptr_t, где-то должно быть определение... в каком-нить хидере. И оно у TI есть

Код
typedef unsigned int uintptr_t;
- т.е. uintptr_t определйн как беззнаковое целочисленное, а не указатель. причем.... как может указатель быть c конкретным размером в 32 бит? указатель может быть на 32-х битное... на структуру, на void. а так-то размер любого указателя одинаковый.
Alechek
Цитата(AHTOXA @ Apr 7 2017, 20:05) *
Совершенно не видно. Может, p_ - это от слова "parameter". А может, просто автор любит писать p_. Или имя осталось от прошлой версии интерфейса функции, когда этот параметр был указателем, а в нынешней версии он уже давно не указатель. В любом случае придётся проверять.

Соглашусь. Сразу не видно. Но заставит задуматься.
Но, если стиль будет одинаков по всему этому однотипному коду (сторонняя библиотека), и с ним уже знаком, то и думать не придется.

Вообще, когда-то пытался использовать принцип FreeRTOS, во времена ее освоения. Понял, что бездумное повальное присвоение префиксов типа в имени переменной и, особенно, функций - путь к граблям и траблам. Поплевался достаточно при рефакторинге своего кода. wacko.gif

Но вот выделение указателей, глобальных переменных (в т.ч. переменных класса) - это святое. Походил уже по граблям безликих переменных, набил шишек. twak.gif

Каждый выбирает свои грабли. smile3046.gif
Forger
Цитата(Alechek @ Apr 7 2017, 18:59) *
Но вот выделение указателей, глобальных переменных (в т.ч. переменных класса) - это святое.

Скажем, имеем указатель на класс.
Компилятор не позволит присвоить ему абы что и не позволит присвоить сам указатель чему-то левому.
Попытка неправильного разыменования полей такого класса тоже невозможна - не получится использовать "." вместо "->"...
Отсюда простой вопрос: зачем в имени указателя на класс указывать тот факт, что он указатель?
Приведите пример, где без этого никак не обойтись.

Какой смысл каким-то образом выделять в имени переменных класса (правильно называть "поля" класса) их расовую принадлежность?
Приведите пример, где без этого никак не обойтись.

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

Цитата
Походил уже по граблям безликих переменных, набил шишек.

Безликость переменной лечится нормальным и осмысленным именем, но никак не префиксами-суффиксами-аппендиксами-подчеркиваниями.

Цитата
Каждый выбирает свои грабли
С этим трудно не солгаситься sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.