|
Область видимости enum, C |
|
|
|
Oct 12 2009, 11:59
|

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

|
На сколько я понял, если в заголовочном файле определено что-то вроде Код enum packetTypes{ IDPacket, BlockPacket }; то пока не определена переменная типа packetTypes - никакой памяти никуда выделяться не будет? Т.е. это почти то-же, что и typedef, только объявили множество. ? Также верно следующее: 1. Определить переменную(в .c/.h файле) так: enum packetTypes packetType; можно только при условии include того заголовочного файле, в котором определен packetTypes 2. В любом другом файле, в котором не было include заголовочного - я никаким образом не смогу добраться до packetTypes. 3. Под enum не выделяется память(в отличие от const). 4. Глобальная переменная, определенная как enum packetTypes packetType; может быть видна из другого файла посредством extern enum packetTypes packetType; при условии, что include сделан( и,таким образом packetTypes определен) 5. Можно ли определить static enum packetTypes packetType; и ограничить область видимости переменной одним файлом?(не вижу причин, почему это может не работать. Но всё-же спрошу) 6. тип enum предполагается int. Как в Си изменить его, скажем, на unsigned int или long? Правильно ли я мыслю? Какие из этих утверждений верны, какие нет? А ещё всегда хотелось иметь под рукой первоисточник. Стандарт Си(какой там щас актуален). Если можно тоже ссылочку. Спасибо. P.S. Навеяно прочтением книги Ален И. Голуб - Правила программирования на Си и Си++ и осознанием того, что моя программа на Си выглядит ужасно и половина возможностей языка осталась "за кадром"
--------------------
The truth is out there...
|
|
|
|
|
Oct 12 2009, 12:20
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата На сколько я понял, если в заголовочном файле определено что-то вроде Код enum packetTypes{ IDPacket, BlockPacket }; то пока не определена переменная типа packetTypes - никакой памяти никуда выделяться не будет? Т.е. это почти то-же, что и typedef, только объявили множество. ? Да. Этим вы определяете тип данных, и множество значений этого типа. Переменную этого типа вы таким образом не объявляете. Цитата Также верно следующее: 1 * * * 5. ДА Цитата 6. тип enum предполагается int. Как в Си изменить его, скажем, на unsigned int или long? Никак. Размер элемента enum всегда равен int
|
|
|
|
|
Oct 12 2009, 12:40
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата 3. Под enum не выделяется память(в отличие от const). Под const тоже память выделяется не всегда: Код const unsigned char MAX_ROWS = 2; будет полностью равнозначно Код #define MAX_ROWS 2 Только в первом случае, если где-то будет MAX_ROWS переопределено (ошибочно), то компилятор выразит свое негодование программистом, а в случае с #define сделает вид что ничего не заметил. Это актуально для С++ и вроде актуально для С99 (для С89 вроде как нет). Цитата Ален И. Голуб - Правила программирования на Си и Си++ могу ошибаться, но книга ОЧЕНЬ старая и там многое устарело, особенно что касается С++.
|
|
|
|
|
Oct 12 2009, 12:41
|

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

|
Ok. Сппсибо. Просто хотел уточнить для верности. На сколько я знаю, Код const unsigned char MAX_ROWS = 2; делает следующее: Создаёт переменную с указанным типом и именем и инициализирует её указанным значением. Так-же, компилятор при этом внимательно следит, чтобы этой переменной ничего не присваивали и ругается, если обнаруживает такую ситуацию. Т.е. память выделяется. Попытка "передефайнить" MAX_ROWS заново будет выдавать предупреждение(мой компилер делает это так). Не знаю как насчёт поределения Код int MAX_ROWS где-то после...вот этого действительно заметить не сможет. Но оно и не страшно вроде как, потому что препроцессор ещё ДО компилятора уже выполнил подстановку и подставит куда нужно циферку 2(в нашем случае)... Но спору нет. Путаница получается. Книга может быть и старая, но вот некоторые советы в ней, кажутся мне бессмертными В С++ пока не вникал, не знаю.....
--------------------
The truth is out there...
|
|
|
|
|
Oct 12 2009, 13:02
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата Создаёт переменную с указанным типом и именем и инициализирует её указанным значением. Ну как бы да, но если он встретит такой вот код (например) Код some_value = MAX_ROWS + 4; то у него будут все основания подставить вместо MAX_ROWS его фактичесное значение (т.к. MAX_ROWS константа, и измениться никаким образом не может). И дополнительной памяти под переменную выделено не будет, каждый раз будет просто подставлятся значение переменной. Цитата Но оно и не страшно вроде как, потому что препроцессор ещё ДО компилятора уже выполнил подстановку и подставит куда нужно циферку 2(в нашем случае) Препроцессор очень злая штука (ОЧЕНЬ ЗЛАЯ!!!). Если где-то в заголовках будет написано #define MAX_ROWS 2, а потом где-то по ошибке будет написано #define MAX_ROWS 4, то может получиться очень неоднозначная ситуация, когда будете думать что должно подставлятся 2, а на самом деле будет подставлятся 4.
|
|
|
|
|
Oct 12 2009, 13:52
|

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

|
Цитата(Dima_G @ Oct 12 2009, 19:20)  Никак. Размер элемента enum всегда равен int А разве это не implementation defined? Цитата(sigmaN @ Oct 12 2009, 19:41)  На сколько я знаю, Код const unsigned char MAX_ROWS = 2; делает следующее: Создаёт переменную с указанным типом и именем и инициализирует её указанным значением. Так-же, компилятор при этом внимательно следит, чтобы этой переменной ничего не присваивали и ругается, если обнаруживает такую ситуацию. Т.е. память выделяется. В С компилятор обязан выделять под константы, объявленные указанным способом, память, т.к. по умолчанию глобальные объекты имеют внешнее связывание - т.е. на них могут быть ссылки из других единиц компиляции. В С++ константы по умолчанию имеют внутреннее связывание - т.е. область видимости такого объекта - scope данной единицы компиляции (файла), и любой вменяемый компилятор не будет под такие объекты выделять память. Конечно, можно заставить компилятор выделить память путем взятия адреса константы либо объявив ее как extern - в последнем случае эта константа явно указана как имеющая внешнее связывание, что приводит ситуацию к той, что в С. И наоборот, в С можно привести поведение константы к С++ному - для этого надо объявить константу как static - это будет ++ная константа. Попробуйте объявить свою константу так.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 12 2009, 14:35
|

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

|
Цитата(sigmaN @ Oct 12 2009, 18:21)  ООоо, а про static к константе я как-то не подумал. Щас посмотрим выделит память или не выделит :-) А что смотреть? Если взятие адреса не происходит, то и в памяти её держать не нужно. static const - есть правильная альтернатива define. За исключением того, что другую константу нельзя инициализировать ей. И ещё, очень красиво на замену define ложится безымянный enum. Вместо: Код #define SOMETHING1 1 #define SOMETHING2 2 #define SOMETHING3 3 используйте: Код enum { SOMETHING1 = 1, SOMETHING2, SOMETHING3 }; Программировать надо на языке программирования, а не на языке препроцессора. ИМХО. Конечно, есть целый класс задач, решающихся с использованием макросов (инициализация полей больших структур значениями по умолчанию например). Но когда можно написать программу красиво и выразительно без использования директив препроцессора, то так и стоит поступать.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 12 2009, 20:50
|

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

|
Однако давно хотел спросить как это так? Код static const int N = 4; static char buf[N]; //error: expression must have a constant value Код #define N 4 static char buf[N]; //OK. Код enum{N = 4}; static char buf[N]; //OK. Комментируем  Компилю под TMS320F28335
--------------------
The truth is out there...
|
|
|
|
|
Oct 12 2009, 22:44
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Может объяснение корявое, но я понимаю так. Вы смешиваете два понятия константы. Константа как число и константа как переменная, не изменяющая нигде внутри единицы компиляции своего значения (объявленная с квалификатором const). В вашем первом примере объявляются два независимых объекта компиляции. Но в момент объявления второго объекта ничего еще не известно о значении первого. Потому, что объявление и инициализация это два разных этапа компиляции. Объявление это выделение места в памяти, а инициализация это присвоение значения уже имеющемуся объекту, под который память уже выделена. Поэтому в стандарте Си имеется явное ограничение на то, что в момент объявления массива его размер должен быть известен (задан константой-числом). Еще про квалификатор const. Другое дело, что компилятор в процессе оптимизации (при повторных проходах) может выкинуть константный объект, подставив его значение "по месту". Но вначале (при первом проходе) компилятор все равно обязан выделить память при объявлении этого константного объекта. Просто вы об этом не (у)знаете. Ну а два последних ваших примера дают всего лишь подстановку на этапе работы препроцессора, еще до этапа компиляции. Выражения эквивалентны Код static char buf[4];
|
|
|
|
|
Oct 13 2009, 00:36
|

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

|
Цитата static const - есть правильная альтернатива define. а в таком простом деле он не позволяет выполнить то, что позволяет #define  Тут нужен enum. Но там, где значение выходит за границы int - enum не прокатывает и приходится использовать const и принципиально правильной назвать нельзя ни одну из альтернатив. rezident, с Вашими рассуждениями нельзя не согласиться. Однако, немного не логично как-то. Если const уже const и его нельзя менять по определению, то почему-бы компилятору не выполнить ту-же подстановку его инициализирующего значения и просто не скомпилить код  Нужно будет написать в SO/IEC, пусть правят
--------------------
The truth is out there...
|
|
|
|
|
Oct 13 2009, 02:35
|

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

|
Цитата(sigmaN @ Oct 13 2009, 03:50)  Комментируем  Компилю под TMS320F28335 Включите С++ режим, и статиков никаких не понадобится, будет собираться и так. Никогда не понимал, зачем использовать С при наличии С++ (ситуации, когда заказчик требует или нужна мегапереносимость, т.е. есть платформы, для которых нет ++, хотя таких уже сегодня по пальцам можно пересчитать, понятны). Даже без всяких классов и прочих плюсатых вещей просто более разумное поведение компилятора в обсуждаемой и подобных (например, работа с enum) ситуациях в сочетании с такими мелочами, как объявление объекта непосредственно перед использованием, уже дает эффект и просто делает сам процесс написания программы более приятным занятием.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 13 2009, 05:27
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(dxp @ Oct 12 2009, 17:52)  А разве это не implementation defined? Да, согласен  Цитата 6.7.2.2 Enumeration specifiers
Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,108) but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until after the } that terminates the list of enumerator declarations. (ISO/IEC 9899:TC2 Committee Draft — May 6, 2005) Цитата(sigmaN @ Oct 13 2009, 06:49)  Почему Linux пишут на Си и не включат режим C++?
P.S. т.е. я Ваш ответ принял. Мне просто интересно. В ядре - политика Торвальдса (ИМХО - зря). Не любит он плюсы. Цитата Linux creator Linus Torvalds joined in to explain: "In fact, in Linux we did try C++ once already, back in 1992. It sucks. Trust me - writing kernel code in C++ is a BLOODY STUPID IDEA.
"The fact is, C++ compilers are not trustworthy. They were even worse in 1992, but some fundamental facts haven't changed: 1) the whole C++ exception handling thing is fundamentally broken. It's _especially_ broken for kernels. 2) any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel. 3) you can write object-oriented code (useful for filesystems etc) in C, _without_ the crap that is C++." http://www.opennet.ru/openforum/vsluhforumID9/8226.htmlА в юзерспейсе - полно приложений на ++;
|
|
|
|
|
Oct 13 2009, 07:31
|

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

|
Цитата(Dima_G @ Oct 13 2009, 12:27)  В ядре - политика Торвальдса (ИМХО - зря). Не любит он плюсы. http://www.opennet.ru/openforum/vsluhforumID9/8226.htmlДа, попадались эти "доводы". Мракобесие, имхо. При всем уважении, дяденька, по ходу, не понимает плюсов. А непонимание порождает боязнь, т.к. вещь кажется неуправляемой. 2 SigmaN: включите режим ++, ничего там страшного нет. Пишите как обычно. Используйте только те средства, которые освоили. И это вполне комфортный и безопасный путь. С++ не заставляет сразу использовать исключения, множественное наследование, темплейты и ООП.  Все это используется в соответствии с задачей. И не бойтесь пробовать. Компилятор С++ в CCS, насколько помню, вполне приличный.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 13 2009, 11:30
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(zltigo @ Oct 13 2009, 13:39)  Если программа не далеко ушла от "Hello World", то разницы не почувствует. Дальше, дальше все не так благостно  . На многие плюсы плюсового компилятора найдутся и свои весьма заметные минусы  . Использовать плюсовый компилятор для компиляции "сишных" исходников не самая хорошая идея, хотя раньше сам много лет так делал. А Вы можете привести примеры минусов С++ комиплятора для Си исходников?
|
|
|
|
|
Oct 13 2009, 13:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Dima_G @ Oct 13 2009, 14:30)  А Вы можете привести примеры минусов С++ комиплятора для Си исходников? На вскидку - incomplete types, неименованные структуры и union-ы, упоминание имени volatile переменной не является причиной обратиться к ней, другой размер литерала, передача параметра по ссылке добавленная для пущей "красоты" мешается, много разных мелочей, типа различия в определениях NULL. Возьмите любую программу приличного размера и просто компильните - различия увидите сами. После появления компиляторов следующих C99 желание пользоваться С++ для компиляции сишных исходников у меня заметно уменьшилось и постепенно сошло на нет. Каждому свое.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 13 2009, 13:55
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(zltigo @ Oct 13 2009, 16:38)  На вскидку - incomplete types, неименованные структуры и union-ы, упоминание имени volatile переменной не является причиной обратиться к ней, другой размер литерала, передача параметра по ссылке добавленная для пущей "красоты" мешается, много разных мелочей, типа различия в определениях NULL. Возьмите любую программу приличного размера и просто компильните - различия увидите сами. После появления компиляторов следующих C99 желание пользоваться С++ для компиляции сишных исходников у меня заметно уменьшилось и постепенно сошло на нет. Каждому свое. Ну в принципе да: С и С++ - это разные языки (впрочем, я так понял, что dxp имел в виду не компиляцию имеющихся сишных исходников, а ведение проекта с нуля, используя некоторые удобства С++, но программируя в си стиле). А можно поподробнее про "упоминание имени volatile переменной не является причиной обратиться к ней" - довольно часто использую в своих проектах на С++ код вида Код volatile DWORD* dwReg_ = reinterpret_cast<DWORD*> (SOME_REGISTER) *dwReg_ = ... а как я понял из ваших слов, в этом случае возможно "необращение" к регистру SOME_REGISTER
|
|
|
|
|
Oct 14 2009, 02:55
|

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

|
Цитата(zltigo @ Oct 13 2009, 20:38)  На вскидку - incomplete types, неименованные структуры и union-ы, упоминание имени volatile переменной не является причиной обратиться к ней, другой размер литерала, передача параметра по ссылке добавленная для пущей "красоты" мешается, много разных мелочей, типа различия в определениях NULL. Возьмите любую программу приличного размера и просто компильните - различия увидите сами. После появления компиляторов следующих C99 желание пользоваться С++ для компиляции сишных исходников у меня заметно уменьшилось и постепенно сошло на нет. Каждому свое. Еще забыли enum'ы, которые в С++ являются именно перечислимым типом, в то время как в С - это просто еще один способ создания целых литералов. И обсуждаемые констатны, подход к которым в С++ куда более разумен. Да, такого рода мелкие отличия есть, и отличия эти в большинстве в лучшую сторону. Мне вообще не понятны мотивы людей, которые с упорством, достойным лучшего применения, продолжают толкать С при наличии более эффективного и уже давно стабильного "надмножества" в виде С++. Что касается ссылок, то это отнюдь не для красоты. Это очень полезная конструкция языка. Без нее, например, невозможно реализовать перегрузку операторов. Да и просто работать с объектами больших (и не очень) размеров куда эффективнее, чем по значению. И ссылки в ряде случаев оказываются хорошей (более безопасной и прозрачной) заменой указателям. Причин для их существования достаточно. И в голом С они бы тоже не помешали. Цитата(Dima_G @ Oct 13 2009, 20:55)  Ну в принципе да: С и С++ - это разные языки (впрочем, я так понял, что dxp имел в виду не компиляцию имеющихся сишных исходников, а ведение проекта с нуля, используя некоторые удобства С++, но программируя в си стиле). Именно это я и имел в виду. Компилять большой проект, написанный на голом С, изобилующий незаконченными массивами, арифметикой с перечислимыми типами и прочим, занятие малополезное и малоприятное. Цитата(sigmaN @ Oct 13 2009, 22:36)  Именно поэтому я и не кинулся тут-же "включать C++"  У вас большой проект, изобилующий чисто сишными феньками, которые упомянул zltigo? Вы пробовали его собирать в С++ режиме? Попробуйте ради интереса, расскажите, на чем споткнулся компилятор?
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 14 2009, 14:57
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(dxp @ Oct 14 2009, 05:55)  Что касается ссылок, то это отнюдь не для красоты. Это очень полезная конструкция языка. Только сделанная с C++ крайне дурно  Цитата И ссылки в ряде случаев оказываются хорошей (более безопасной и прозрачной) заменой указателям. Я бы сказал, что именно в C++ реализации, с точностью до наоборот  . Цитата ...изобилующий незаконченными массивами Ну это ничуть не лучше, чем изощрятся в странных и непрозрачных действиях с обходом реальностей ввиде незаконченных массивов  и тех-же лишних ненужных имен для обязательно именованных структур. Просто 'C99' на сегодняшний день вполне продуманный, законченный и сбалансированый язык. Для эмбеддерских целей с переходом на C++ привязка к конкретному компилятору становится заметно жестче  , если конечно не писать "Hello World!" с "контроллерами светодиодов". Цитата Попробуйте ради интереса, расскажите, на чем споткнулся компилятор? Естественно, что кондовый вариант скорее всего скушает. Хотя... Я тут прямо сейчас влет попробовал недавно писанный, под AVR практически буквально "контроллер светодиодов", который по идее должен был без проблем компилиться и плюсовым, но тем не менее споткнулся на __flash char HexChars[16] = "0123456789ABCDEF";  Проблема выбора между фенечками 'C' и фенечками 'C++'  Я, как уже писал, последнее время склонился к фенечкам 'C99'. Естественно, для случаев, когда идет речь именно о фенечках, а не о полезности фундаментальных отличий C++.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 14 2009, 19:15
|

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

|
Потом как-нибудь попробую. Проект не супер большой, но и не hello world и не мигалка диодами. После компиляции .text получается размером ~150КБ (TMS320F28335) Но, хотя, внутренний голос подсказывает мне не переходить на C++ для достаточно простых проектов, где можно обойтись структурным подходом - я всё-же попробую. Чисто ради интереса.  А ещё дело пока осложняется тем, что я по сути только начинаю привыкать к фенечкам C и боюсь перемешать всё начисто, так и не разобравшись толком... Короче ещё немного с фенечками Си повожусь, а потом на C++. Ну а потом, может быть, как zltigo переползу обратно к Си. И тогда у меня будут более существенные чем просто "внутренний голос подсказывает"аргументы
--------------------
The truth is out there...
|
|
|
|
|
Oct 15 2009, 03:41
|

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

|
Цитата(zltigo @ Oct 14 2009, 21:57)  Только сделанная с C++ крайне дурно  Обоснуйте, пожалуйста. На примере. Цитата(zltigo @ Oct 14 2009, 21:57)  Я бы сказал, что именно в C++ реализации, с точностью до наоборот  . Обоснуйте, пожалуйста. Тоже на примере. Цитата(zltigo @ Oct 14 2009, 21:57)  Ну это ничуть не лучше, чем изощрятся в странных и непрозрачных действиях с обходом реальностей ввиде незаконченных массивов  Ничего не понял. Цитата(zltigo @ Oct 14 2009, 21:57)  и тех-же лишних ненужных имен для обязательно именованных структур. Опять не понял о чем речь.  Каких ненужных имен? Что такое обязательно именованные структуры? Цитата(zltigo @ Oct 14 2009, 21:57)  Просто 'C99' на сегодняшний день вполне продуманный, законченный и сбалансированый язык. Который реально ничем не лучше С++. И значительно слабее в принципе. Цитата(zltigo @ Oct 14 2009, 21:57)  Для эмбеддерских целей с переходом на C++ привязка к конкретному компилятору становится заметно жестче  , если конечно не писать "Hello World!" с "контроллерами светодиодов". Так было несколько лет назад (5+). Но сегодня ситуация уже совсем иная. Платформ в embedded, для которых есть С и нет С++, по пальцам можно пересчитать. Цитата(zltigo @ Oct 14 2009, 21:57)  Естественно, что кондовый вариант скорее всего скушает. Хотя... Я тут прямо сейчас влет попробовал недавно писанный, под AVR практически буквально "контроллер светодиодов", который по идее должен был без проблем компилиться и плюсовым, но тем не менее споткнулся на __flash char HexChars[16] = "0123456789ABCDEF"; И об какое ограничеие С++ тут споткнулся компилятор? Цитата(zltigo @ Oct 14 2009, 21:57)  Проблема выбора между фенечками 'C' и фенечками 'C++'  Я, как уже писал, последнее время склонился к фенечкам 'C99'. Естественно, для случаев, когда идет речь именно о фенечках, а не о полезности фундаментальных отличий C++. С++, если его использовать именно как С++, а не только как "улучшенный С" (что приемлемо только на начальном этапе, а дальше надо расти), дает колоссальные преимущества перед С в первую очередь в том, что порождает иной способ мышления при программировании - поощряет подход, когда программист видит в программе не просто переменные и функции, а объекты, имеющие непосредственное отношение к объектам реального мира. Позволяет выстраивать в программе иерархию объектов и организовать между ними органичные связи так, что эта система объектов и связей является отражением своего "прототипа" из реального мира... В С тоже можно подходить так же, но сам язык никак не поддерживает это, поэтому тут придется напрягаться и появится немало "технологического" кода. Про возможности ООП. В последнем проекте пришлось разрабатывать GUI. Вообще не понимаю, как работать с GUI без возможностей наследования и полиморфизма. Как представлю, что все это пришлось бы реализовывать на голом С, так просто паника подкатывает.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 15 2009, 04:11
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(zltigo @ Oct 14 2009, 18:57)  Я тут прямо сейчас влет попробовал недавно писанный, под AVR практически буквально "контроллер светодиодов", который по идее должен был без проблем компилиться и плюсовым, но тем не менее споткнулся на __flash char HexChars[16] = "0123456789ABCDEF"; Тут всего лишь более строгий контроль, который предоставляет компилятор С++. С его точки зрения - это попытка проинициализировать массив из 16 char строкой, длиной 17 char (включая терминальный ноль).
|
|
|
|
|
Oct 15 2009, 13:56
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(dxp @ Oct 15 2009, 06:41)  Обоснуйте, пожалуйста. На примере. function( a ); Скажите, пожалуйста, как в данном конкретном случае (С++) передается параметр 'a' по ссылке, или по значению? Цитата Каких ненужных имен? Что такое обязательно именованные структуры? Тут ошибся  - редко на плюсах пишу - привиделось. Зато вспомнилось такое Цитата struct aaa { const int aa; }; Ну очень заботливый IAR C++ компилятор ругался. Цитата Так было несколько лет назад (5+). Но сегодня ситуация уже совсем иная. Платформ в embedded, для которых есть С и нет С++, по пальцам можно пересчитать. Речь идет не о том, декларировано наличие какого-либо ПОДМНОЖЕСТВА C++ для embedded компилятора, а в том, насколько эти усеченные реализации СОВПАДАЮТ у разных компиляторов. Я вот относительно недавно замаялся один чужой C++ проект для банального x86 править под Watcom компилятор - плюнул и Visual Studio взгромоздил. Цитата Про возможности ООП. В последнем проекте пришлось разрабатывать GUI. Вообще не понимаю, как работать с GUI без возможностей наследования и полиморфизма. Как представлю, что все это пришлось бы реализовывать на голом С, так просто паника подкатывает.   О это да. По иронии судьбы мои первые сишные опыты были на C++. Только появился свежайший Turbo C++ V1.0 компилятор, свободная IBM PC/XT и... На спор с уже достаточно опытным сишным программистом наперегонки, и с выжиманием СКОРОСТИ начали писать псевдографическую оконную библиотеку для порграмматора и с дальнейшим ее развитием под терминал тестовой системы. Короче, зеленый совсем, но победил за пару недель вечерних работ тогда я  . Уж больно все классически идеально все сие на плюсы ложилось. В буквальном смысле компилятор думал и делал за программиста очень многое. Потом... потом правда спустя несколько лет выжимание всего и вся для работы на 4.7MHz (не путать с гигагерцами  ) XT привело к переводу ее-;t на 'C', к заметному использованию ASM... И стал меня и 'C' в большинстве случаев очень даже устраивать.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 15 2009, 15:19
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата Скажите, пожалуйста, как в данном конкретном случае (С++) передается параметр 'a' по ссылке, или по значению? У меня есть куча строчек вида Код KOG PP2 (str_PP04, mPP2, OP_PP2, K_PP2, inSchpz.PP_status[1]); Это передача параметра по ссылке при инициализации объекта. Мне уже легче, что не нужно каждый раз крякозяблу (&) ставить "для понятности". К тому-же ее можно случайно забыть поставить и тогда вместо адреса будет передаваться непонятно что, ну а дальше результат непредсказуем.
|
|
|
|
|
Oct 15 2009, 16:06
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(kurtis @ Oct 15 2009, 18:19)  ну а дальше результат непредсказуем. Не будет, контроль типов никто не отменял. P.S. Ну а о рассуждать "понятливости" с теми, кто переменные называет OP_PP2, K_PP2.... вообще не хочется  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 15 2009, 16:39
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата(zltigo @ Oct 15 2009, 19:06)  Ну а о рассуждать "понятливости" с теми, кто переменные называет OP_PP2, K_PP2.... вообще не хочется  . могу ответить Вам точно так-же, если не знаете почему они так называются, то лучше не делайте поспешных выводов, считайте это внутрифирменным стандартом Забыл упомянуть очень важный момент. Если передать параметр через ссылку, то с ней далее очень удобно работать. Если функция (или метод) достаточно большая, то можно элементарно забыть где-то поставить нужную звездочку и спокойно сделать операцию над указателем, тут уже никакой контроль типов не спасет.
|
|
|
|
|
Oct 15 2009, 18:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(kurtis @ Oct 15 2009, 19:39)  могу ответить Вам точно так-же, если не знаете почему они так называются Меня не интересует почему, мне достаточно знания того, что имена переменных не должны писаться заглавными буквами. И Цитата считайте это внутрифирменным стандартом мне безразлично один Вы такой или там вас целая фирма  . Цитата о с ней далее очень удобно работать и заодно многочисленные дополнительные операции разименовывания не видны и совесть эмбеддера не мучают - тишь да гладь в плюсовом исходнике
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 16 2009, 09:20
|

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

|
Цитата(zltigo @ Oct 16 2009, 11:27)  типа совершенно не важно, изменится-ли значение 'a' после вызова этой функции??? Передавая указатель вы получаете такую же неопределенность. Может изменить, а может и не изменить. Даже если указатель в параметре описан как указатель на константный объект - его можно внутри функции грубой силой привести к указателю на неконстантный. Цитата(zltigo @ Oct 16 2009, 11:27)  Боюсь,что лично для меня это слишком высокий уровень пофигизма абстракции  . Ну, как горорил один мой бывший шеф, имеющий первое высшее образование - медицинское, "сдуру можно и х.. сломать".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 16 2009, 10:27
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Oct 16 2009, 12:20)  Передавая указатель вы получаете такую же неопределенность. Может изменить, а может и не изменить. Ну если пуститься в схоластические рассуждения, то дело В САМОМ ФАКТЕ ВОЗМОЖНОСТИ ИЗМЕНЕНИЯ в одном случае и гарантированной НЕ возможности в другом. Делать эти два случая неразличимыми - ДУРНО. О чем я собственно и написал в начале. К тому как что-либо, в том числе и передача по ссылке, реализовано Виртом надо относится с большим вниманием. А так, да в принципе для обеспечения более строгой работы с объектом по ссылке, нежели через указатель вещь не бесполезная. Наверное кому-то поможет, хотя с точки зрения минимализма и универсализма достаточно указателей. Причем поскольку наличие ссылок не покрывает возможности указателей, то культуру работы с указателями по любому надо в себе воспитывать. Умение уверено обращаться с указателями, делает лично для меня наличие передачи параметра по ссылке не сильно привлекательной.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 17 2009, 07:21
|

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

|
Цитата(zltigo @ Oct 16 2009, 15:27)  типа совершенно не важно, изменится-ли значение 'a' после вызова этой функции??? Боюсь,что лично для меня это слишком высокий уровень пофигизма абстракции  . Если для важно, чтобы объект не менялся, то надо и тип аргумента задавать соответствующий - с квалификатором const. Это во всех смыслах полезно - и защита от ошибок, и повышает читабельность кода. И тогда void f(const int A& x) { ... } совершенно ясно, что передаваемый объект не изменяется. А если без константы - то сразу подразумевается, что изменяется. Кстати, заметил, что в С-сообществе культура использования const как-то не очень развита. Очевидно, это происходит оттого, что сами по себе константы более накладны, и вместо них предпочитают использовать макросы препроцессора.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 17 2009, 08:06
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(dxp @ Oct 17 2009, 10:21)  Если для важно, чтобы объект не менялся.... Ну естествено, речь идет не о грубом варианте не изменения объекта никогда  (что само по себе вырожденный случай для ссылок), а о банальной заметности того важного факта, что в функция работает с собственно объектом и о том, что о возможных последствиями этого факта надо не забыть. Цитата Кстати, заметил, что в С-сообществе культура использования const как-то не очень развита. Лично я использую достаточно широко, в том числе достаточно часто прикрываю const некоторые элементы структур - конечно, своеобразный костыль  по сравнению с возможностями С++  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|