Forger 17 6 апреля, 2017 Опубликовано 6 апреля, 2017 · Жалоба А ни разу не сталкивались, когда при очередной модификации кода (через 10*N месяцев) в 16 бит переменной (поле структуры) нечаянно пытались освоить биты >16? Ну, да, действительно - гораздо разумнее весь код загромождать избыточной информацией ради гипотетической штучной проблемы с переполнением "через 10*N месяцев". В таком случае, предлагаю в название переменной добавлять не только ее тип, а еще секцию памяти, где она лежит, область видимости, дату ее создания и еще бог знает что Кроме шуток, существует весьма полезная вещь - sizeof, или для более продвинутых: (1 << ( sizeof(...)*8 ) ) - 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 6 апреля, 2017 Опубликовано 6 апреля, 2017 · Жалоба А ни разу не сталкивались, когда при очередной модификации кода (через 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 17 6 апреля, 2017 Опубликовано 6 апреля, 2017 · Жалоба и второй подход - это битовые поля А, если еще компилятор поддерживает безымянные объединения, то получается полный феньшуй: 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 0 6 апреля, 2017 Опубликовано 6 апреля, 2017 · Жалоба нет, ни разу. никогда к битам не обращяюсь напрямую типа a |= (1 << 24); Только через дефайны. a |= STATE_A; Счастливчик. Только увы, биты можно освоить и простым сложением величин... А потом долго не втыкать, почему же с = a+b не работает...Или с = a - b, если b > a... А все было бы гораздо прозрачней, если usC = iA - iB Еще интересней случаи, когда Data = N; вместо *Data = N; а с *pData = N; сделать ошибку куда сложней. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 6 апреля, 2017 Опубликовано 6 апреля, 2017 · Жалоба А все было бы гораздо прозрачней, если usC = iA - iB © "Ежики кололись, но все равно ели кактус" :) *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" зы. Честно, прям дикости какие-то вы тут пишите У меня никогда не было подобных проблем с неправильным присвоением указателя и т. п. Может, это связано с тем, что трачу уйму времени на предварительно проектирование кода ... не знаю, но факт в том, что в своем коде никогда не шифрую тип переменной в ее названии и никогда от этого не было проблем, а лишь наоборот. Хотя раньше указатели я именовал, но не шифровками типа - "p" или "ptr", а с полностью - с припиской "Pointer" в конце названия. В данный момент указателей практически нет, кроме редких случаем в низкоуровневых драйверах да и то крайне редко, всегда стараюсь избегать указатели в коде. Это несложно, т. к. пишу под плюсами, поэтому использую ссылки, а не указатели. Так безопаснее да и код читается лучше, т.к. нет "->". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Еще интересней случаи, когда 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 и более бита - используйте битовые поля, обращайтесь к ним как к простым переменным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба (ее нет в С++):Там "из коробки" специально для этого есть nullptr. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Forger, juvf, вы сильно зацикливаетесь на своем коде. Я рад за вас, что вы сразу пишете идеальный код. Не у всех так получается. А люди еще бывает работают в команде. А еще бывает, люди пишут код, который потом будут массово пользовать другие (как те же библиотеки stm32). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Там "из коробки" специально для этого есть nullptr. Это относится лишь к компиляторам, которые поддерживают C++11. В ARM-компиляторе (Keil) есть частичная поддержка C++11, nullptr в его редакторе подкрашивается, это удобно )) "Из коробки" не заработает, нужно обязательно включать опцию компилятора "--cpp11". Но обязательно возьму на вооружение! Спасибо Не у всех так получается.Неправда - у всех это получается, ничего тут сложного нет. А дело, возможно, в другом - не все хотят учится и переучиваться ;) А люди еще бывает работают в команде. Тем более! Логичнее приучить всю команду сразу писать правильно, создав свод правил или использовать готовые, как тут уже писали,. Ведь на то она и команда, чтобы следовать единым и удобным для всех правилам, а не писать каждый как хочет! Придется все же выбрать: общие правила (законы) или "ежики кололись, но продолжали есть кактус" (повторяюсь) :smile3046: А еще бывает, люди пишут код, который потом будут массово пользовать другие (как те же библиотеки stm32). Какое странное оправдание .. . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Какое странное оправдание ... Ладно, последняя попытка B) Не все пишут на С++ и С++11 Те же библиотеки stm32 написаны на С. А ему пофиг на int value = 10; int * pointer; .... pointer = value; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Не все пишут на С++ и С++11 Это тут ни при чем. Я использую C-библиотеки stm32 в C++. Неразрешимых проблем не было. Те же библиотеки stm32 написаны на С. А ему пофиг на int value = 10; int * pointer; .... pointer = value; Так смените свой компилятор на нормальный, которому это не пофиг! Или покопайтесь в настройках компилятора, чтобы он ругался на такие вещи хотя бы warning-ми. Честно слово, как дети малые ... зы. Скажите, при сборке всего проекта вы сразу добиваетесь, чтобы не было ни одного warning-а или откладываете это на потом? ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Forger, juvf, вы сильно зацикливаетесь на своем коде. Я рад за вас, что вы сразу пишете идеальный код. Не у всех так получается. А люди еще бывает работают в команде. А еще бывает, люди пишут код, который потом будут массово пользовать другие (как те же библиотеки stm32). Я не зациклен. Я предложил свой стаил. Он не единственно верный. Гугл стайл мне не понравился... тип переменной в имя сувать - тоже мне не по вкусу. раньше вроде так писали int *pName; Сечас..... посмотрите другие стайлы.... мой стаил гавно? посмотрите гугл, Qt,.... посмотрите исходники Linux - это пуре СИ. Те же библиотеки stm32 написаны на С. А ему пофиг наиаровски СИШНЫЙ компилятр не скомпилировал такое, ругнулся int *i; i = 200; gcc тоже такое не проглотит. Не нужно нормальный компилятор. мне кажется не один компилятор такое не проглотит. Или я ошибаюсь? Какой компиллер такое проглитит? Я не пишу идеальный код сразу и правильно.... но мне эти р не нужны. Более того, они мне мешают. Если вам с ними комфортно, с ними меньше ошибок и быстрее пишется - ни кто вам не запрещяет ставить р. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 30 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба иаровски СИШНЫЙ компилятр не скомпилировал такое, ругнулся 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 10 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Отцы, вам самим не смешно такие примеры приводить?не в тему сказал. войди в тему, начни читать с 109 поста. вместе посмеёмся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 7 апреля, 2017 Опубликовано 7 апреля, 2017 · Жалоба Позвольте зацитировать первооснователей (K&R): int х = 1, у = 2, z[10]; int *ip; /* ip - указатель на int */ ip = &x; /* теперь ip указывает на х */ y = *ip; /* у теперь равен 1 */ *ip =0; /* х теперь равен 0 */ выделено мной. Такую "кашу" из букв даже при желании сочинить трудно, определенно нужен "талант"! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться