Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Область видимости enum
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
sigmaN
На сколько я понял, если в заголовочном файле определено что-то вроде
Код
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. Навеяно прочтением книги Ален И. Голуб - Правила программирования на Си и Си++ и осознанием того, что моя программа на Си выглядит ужасно и половина возможностей языка осталась "за кадром" smile.gif
Dima_G
Цитата
На сколько я понял, если в заголовочном файле определено что-то вроде
Код
enum packetTypes{ IDPacket, BlockPacket };
то пока не определена переменная типа packetTypes - никакой памяти никуда выделяться не будет? Т.е. это почти то-же, что и typedef, только объявили множество. ?


Да. Этим вы определяете тип данных, и множество значений этого типа. Переменную этого типа вы таким образом не объявляете.

Цитата
Также верно следующее:
1
* * *
5.

ДА

Цитата
6. тип enum предполагается int. Как в Си изменить его, скажем, на unsigned int или long?


Никак. Размер элемента enum всегда равен int
kurtis
Цитата
3. Под enum не выделяется память(в отличие от const).

Под const тоже память выделяется не всегда:
Код
const unsigned char MAX_ROWS = 2;
будет полностью равнозначно
Код
#define MAX_ROWS 2

Только в первом случае, если где-то будет MAX_ROWS переопределено (ошибочно), то компилятор выразит свое негодование программистом, а в случае с #define сделает вид что ничего не заметил.
Это актуально для С++ и вроде актуально для С99 (для С89 вроде как нет).

Цитата
Ален И. Голуб - Правила программирования на Си и Си++

могу ошибаться, но книга ОЧЕНЬ старая и там многое устарело, особенно что касается С++.
sigmaN
Ok. Сппсибо. Просто хотел уточнить для верности.

На сколько я знаю,
Код
const unsigned char MAX_ROWS = 2;
делает следующее:
Создаёт переменную с указанным типом и именем и инициализирует её указанным значением. Так-же, компилятор при этом внимательно следит, чтобы этой переменной ничего не присваивали и ругается, если обнаруживает такую ситуацию. Т.е. память выделяется.

Попытка "передефайнить" MAX_ROWS заново будет выдавать предупреждение(мой компилер делает это так). Не знаю как насчёт поределения
Код
int MAX_ROWS
где-то после...вот этого действительно заметить не сможет. Но оно и не страшно вроде как, потому что препроцессор ещё ДО компилятора уже выполнил подстановку и подставит куда нужно циферку 2(в нашем случае)... Но спору нет. Путаница получается.

Книга может быть и старая, но вот некоторые советы в ней, кажутся мне бессмертными smile.gif
В С++ пока не вникал, не знаю.....
kurtis
Цитата
Создаёт переменную с указанным типом и именем и инициализирует её указанным значением.

Ну как бы да, но если он встретит такой вот код (например)
Код
some_value = MAX_ROWS + 4;
то у него будут все основания подставить вместо MAX_ROWS его фактичесное значение (т.к. MAX_ROWS константа, и измениться никаким образом не может). И дополнительной памяти под переменную выделено не будет, каждый раз будет просто подставлятся значение переменной.

Цитата
Но оно и не страшно вроде как, потому что препроцессор ещё ДО компилятора уже выполнил подстановку и подставит куда нужно циферку 2(в нашем случае)

Препроцессор очень злая штука (ОЧЕНЬ ЗЛАЯ!!!). Если где-то в заголовках будет написано #define MAX_ROWS 2, а потом где-то по ошибке будет написано #define MAX_ROWS 4, то может получиться очень неоднозначная ситуация, когда будете думать что должно подставлятся 2, а на самом деле будет подставлятся 4.
Сергей Борщ
Цитата(sigmaN @ Oct 12 2009, 14:59) *
6. тип enum предполагается int. Как в Си изменить его, скажем, на unsigned int или long?
Компиляторы обычно имеют галочку типа "выделять минимально необходимый тип". В gcc это -fshort-enums, у IAR такое поведение вообще единственно возможное ("если нужен тип больше, объявите в списке значение с достаточно большим значением").
dxp
Цитата(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 - это будет ++ная константа. Попробуйте объявить свою константу так. smile.gif
sigmaN
ООоо, а про static к константе я как-то не подумал. Щас посмотрим выделит память или не выделит :-)
Палыч
Цитата(sigmaN @ Oct 12 2009, 14:59) *
А ещё всегда хотелось иметь под рукой первоисточник.


http://www.onlinedisk.ru/file/239872/
demiurg_spb
Цитата(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
};
Программировать надо на языке программирования, а не на языке препроцессора. ИМХО.
Конечно, есть целый класс задач, решающихся с использованием макросов (инициализация полей больших структур значениями по умолчанию например).
Но когда можно написать программу красиво и выразительно без использования директив препроцессора, то так и стоит поступать.
sigmaN
Однако давно хотел спросить как это так?
Код
    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.

Комментируем smile.gif
Компилю под TMS320F28335
rezident
Может объяснение корявое, но я понимаю так.
Вы смешиваете два понятия константы. Константа как число и константа как переменная, не изменяющая нигде внутри единицы компиляции своего значения (объявленная с квалификатором const).
В вашем первом примере объявляются два независимых объекта компиляции. Но в момент объявления второго объекта ничего еще не известно о значении первого. Потому, что объявление и инициализация это два разных этапа компиляции. Объявление это выделение места в памяти, а инициализация это присвоение значения уже имеющемуся объекту, под который память уже выделена. Поэтому в стандарте Си имеется явное ограничение на то, что в момент объявления массива его размер должен быть известен (задан константой-числом).
Еще про квалификатор const. Другое дело, что компилятор в процессе оптимизации (при повторных проходах) может выкинуть константный объект, подставив его значение "по месту". Но вначале (при первом проходе) компилятор все равно обязан выделить память при объявлении этого константного объекта. Просто вы об этом не (у)знаете.
Ну а два последних ваших примера дают всего лишь подстановку на этапе работы препроцессора, еще до этапа компиляции. Выражения эквивалентны
Код
static char buf[4];
sigmaN
Цитата
static const - есть правильная альтернатива define.
а в таком простом деле он не позволяет выполнить то, что позволяет #define smile.gif
Тут нужен enum. Но там, где значение выходит за границы int - enum не прокатывает и приходится использовать const и принципиально правильной назвать нельзя ни одну из альтернатив.

rezident, с Вашими рассуждениями нельзя не согласиться. Однако, немного не логично как-то. Если const уже const и его нельзя менять по определению, то почему-бы компилятору не выполнить ту-же подстановку его инициализирующего значения и просто не скомпилить код smile.gif Нужно будет написать в SO/IEC, пусть правят biggrin.gif
rezident
Цитата(sigmaN @ Oct 13 2009, 06:36) *
Это я к тому, что а на таком простом деле он не позволяет выполнить то, что позволяет #define smile.gif
ЯВУ он потому и высокого уровня, что позволяет весьма просто объяснить компилятору то, что вы от него хотите. Однако компилятор это тоже программа, которая не может "домысливать" за человека и поэтому работает в рамках описанных правил и стандартов. Общеизвестно, что любая программа не умнее программиста, написавшего ее laughing.gif
dxp
Цитата(sigmaN @ Oct 13 2009, 03:50) *
Комментируем smile.gif
Компилю под TMS320F28335

Включите С++ режим, и статиков никаких не понадобится, будет собираться и так. Никогда не понимал, зачем использовать С при наличии С++ (ситуации, когда заказчик требует или нужна мегапереносимость, т.е. есть платформы, для которых нет ++, хотя таких уже сегодня по пальцам можно пересчитать, понятны). Даже без всяких классов и прочих плюсатых вещей просто более разумное поведение компилятора в обсуждаемой и подобных (например, работа с enum) ситуациях в сочетании с такими мелочами, как объявление объекта непосредственно перед использованием, уже дает эффект и просто делает сам процесс написания программы более приятным занятием.
sigmaN
Почему Linux пишут на Си и не включат режим C++?

P.S. т.е. я Ваш ответ принял. Мне просто интересно.
Dima_G
Цитата(dxp @ Oct 12 2009, 17:52) *
А разве это не implementation defined?


Да, согласен smile.gif


Цитата
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

А в юзерспейсе - полно приложений на ++;
dxp
Цитата(Dima_G @ Oct 13 2009, 12:27) *
В ядре - политика Торвальдса (ИМХО - зря). Не любит он плюсы.

http://www.opennet.ru/openforum/vsluhforumID9/8226.html

Да, попадались эти "доводы". Мракобесие, имхо. При всем уважении, дяденька, по ходу, не понимает плюсов. А непонимание порождает боязнь, т.к. вещь кажется неуправляемой.

2SigmaN: включите режим ++, ничего там страшного нет. Пишите как обычно. Используйте только те средства, которые освоили. И это вполне комфортный и безопасный путь. С++ не заставляет сразу использовать исключения, множественное наследование, темплейты и ООП. smile.gif Все это используется в соответствии с задачей. И не бойтесь пробовать. Компилятор С++ в CCS, насколько помню, вполне приличный.
sigmaN
Ok. В следующем проекте попробуем smile.gif
zltigo
Цитата(dxp @ Oct 13 2009, 10:31) *
2SigmaN: включите режим ++, ничего там страшного нет. Пишите как обычно.

Если программа не далеко ушла от "Hello World", то разницы не почувствует. Дальше, дальше все не так благостно sad.gif. На многие плюсы плюсового компилятора найдутся и свои весьма заметные минусы sad.gif. Использовать плюсовый компилятор для компиляции "сишных" исходников не самая хорошая идея, хотя раньше сам много лет так делал.
Dima_G
Цитата(zltigo @ Oct 13 2009, 13:39) *
Если программа не далеко ушла от "Hello World", то разницы не почувствует. Дальше, дальше все не так благостно sad.gif. На многие плюсы плюсового компилятора найдутся и свои весьма заметные минусы sad.gif. Использовать плюсовый компилятор для компиляции "сишных" исходников не самая хорошая идея, хотя раньше сам много лет так делал.


А Вы можете привести примеры минусов С++ комиплятора для Си исходников?
zltigo
Цитата(Dima_G @ Oct 13 2009, 14:30) *
А Вы можете привести примеры минусов С++ комиплятора для Си исходников?

На вскидку - incomplete types, неименованные структуры и union-ы, упоминание имени volatile переменной не является причиной обратиться к ней, другой размер литерала, передача параметра по ссылке добавленная для пущей "красоты" мешается, много разных мелочей, типа различия в определениях NULL.
Возьмите любую программу приличного размера и просто компильните - различия увидите сами. После появления компиляторов следующих C99 желание пользоваться С++ для компиляции сишных исходников у меня заметно уменьшилось и постепенно сошло на нет. Каждому свое.
Dima_G
Цитата(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 unsure.gif
zltigo
Цитата(Dima_G @ Oct 13 2009, 16:55) *
а как я понял из ваших слов, в этом случае возможно "необращение" к регистру SOME_REGISTER unsure.gif

Нет не в этом, а в этом:
Код
*dwReg_;
sigmaN
Именно поэтому я и не кинулся тут-же "включать C++" wink.gif
dxp
Цитата(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++" wink.gif

У вас большой проект, изобилующий чисто сишными феньками, которые упомянул zltigo? Вы пробовали его собирать в С++ режиме? Попробуйте ради интереса, расскажите, на чем споткнулся компилятор?
zltigo
Цитата(dxp @ Oct 14 2009, 05:55) *
Что касается ссылок, то это отнюдь не для красоты. Это очень полезная конструкция языка.

Только сделанная с C++ крайне дурно sad.gif
Цитата
И ссылки в ряде случаев оказываются хорошей (более безопасной и прозрачной) заменой указателям.

Я бы сказал, что именно в C++ реализации, с точностью до наоборот sad.gif.
Цитата
...изобилующий незаконченными массивами

Ну это ничуть не лучше, чем изощрятся в странных и непрозрачных действиях с обходом реальностей ввиде незаконченных массивов sad.gif и тех-же лишних ненужных имен для обязательно именованных структур. Просто 'C99' на сегодняшний день вполне продуманный, законченный и сбалансированый язык. Для эмбеддерских целей с переходом на C++ привязка к конкретному компилятору становится заметно жестче sad.gif, если конечно не писать "Hello World!" с "контроллерами светодиодов".
Цитата
Попробуйте ради интереса, расскажите, на чем споткнулся компилятор?

Естественно, что кондовый вариант скорее всего скушает. Хотя... Я тут прямо сейчас влет попробовал недавно писанный, под AVR практически буквально "контроллер светодиодов", который по идее должен был без проблем компилиться и плюсовым, но тем не менее споткнулся на
__flash char HexChars[16] = "0123456789ABCDEF";
smile.gif
Проблема выбора между фенечками 'C' и фенечками 'C++' sad.gif Я, как уже писал, последнее время склонился к фенечкам 'C99'. Естественно, для случаев, когда идет речь именно о фенечках, а не о полезности фундаментальных отличий C++.
sigmaN
Потом как-нибудь попробую.
Проект не супер большой, но и не hello world и не мигалка диодами.
После компиляции .text получается размером ~150КБ (TMS320F28335)

Но, хотя, внутренний голос подсказывает мне не переходить на C++ для достаточно простых проектов, где можно обойтись структурным подходом - я всё-же попробую.
Чисто ради интереса. smile.gif
А ещё дело пока осложняется тем, что я по сути только начинаю привыкать к фенечкам C и боюсь перемешать всё начисто, так и не разобравшись толком...
Короче ещё немного с фенечками Си повожусь, а потом на C++. Ну а потом, может быть, как zltigo переползу обратно к Си.
И тогда у меня будут более существенные чем просто "внутренний голос подсказывает"аргументы smile.gif
dxp
Цитата(zltigo @ Oct 14 2009, 21:57) *
Только сделанная с C++ крайне дурно sad.gif

Обоснуйте, пожалуйста. На примере.


Цитата(zltigo @ Oct 14 2009, 21:57) *
Я бы сказал, что именно в C++ реализации, с точностью до наоборот sad.gif.

Обоснуйте, пожалуйста. Тоже на примере.

Цитата(zltigo @ Oct 14 2009, 21:57) *
Ну это ничуть не лучше, чем изощрятся в странных и непрозрачных действиях с обходом реальностей ввиде незаконченных массивов sad.gif

Ничего не понял.

Цитата(zltigo @ Oct 14 2009, 21:57) *
и тех-же лишних ненужных имен для обязательно именованных структур.

Опять не понял о чем речь. sad.gif Каких ненужных имен? Что такое обязательно именованные структуры?

Цитата(zltigo @ Oct 14 2009, 21:57) *
Просто 'C99' на сегодняшний день вполне продуманный, законченный и сбалансированый язык.

Который реально ничем не лучше С++. И значительно слабее в принципе.

Цитата(zltigo @ Oct 14 2009, 21:57) *
Для эмбеддерских целей с переходом на C++ привязка к конкретному компилятору становится заметно жестче sad.gif, если конечно не писать "Hello World!" с "контроллерами светодиодов".

Так было несколько лет назад (5+). Но сегодня ситуация уже совсем иная. Платформ в embedded, для которых есть С и нет С++, по пальцам можно пересчитать.


Цитата(zltigo @ Oct 14 2009, 21:57) *
Естественно, что кондовый вариант скорее всего скушает. Хотя... Я тут прямо сейчас влет попробовал недавно писанный, под AVR практически буквально "контроллер светодиодов", который по идее должен был без проблем компилиться и плюсовым, но тем не менее споткнулся на
__flash char HexChars[16] = "0123456789ABCDEF";

И об какое ограничеие С++ тут споткнулся компилятор?

Цитата(zltigo @ Oct 14 2009, 21:57) *
Проблема выбора между фенечками 'C' и фенечками 'C++' sad.gif Я, как уже писал, последнее время склонился к фенечкам 'C99'. Естественно, для случаев, когда идет речь именно о фенечках, а не о полезности фундаментальных отличий C++.

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

Про возможности ООП. В последнем проекте пришлось разрабатывать GUI. Вообще не понимаю, как работать с GUI без возможностей наследования и полиморфизма. Как представлю, что все это пришлось бы реализовывать на голом С, так просто паника подкатывает. smile.gif
Dima_G
Цитата(zltigo @ Oct 14 2009, 18:57) *
Я тут прямо сейчас влет попробовал недавно писанный, под AVR практически буквально "контроллер светодиодов", который по идее должен был без проблем компилиться и плюсовым, но тем не менее споткнулся на
__flash char HexChars[16] = "0123456789ABCDEF";


Тут всего лишь более строгий контроль, который предоставляет компилятор С++. С его точки зрения - это попытка проинициализировать массив из 16 char строкой, длиной 17 char (включая терминальный ноль).
dxp
Цитата(Dima_G @ Oct 15 2009, 11:11) *
Тут всего лишь более строгий контроль, который предоставляет компилятор С++. С его точки зрения - это попытка проинициализировать массив из 16 char строкой, длиной 17 char (включая терминальный ноль).

Да, точно, не сообразил сразу (на __flash засмотрелся). smile.gif Сишный компилятор выдает предупреждение.
zltigo
Цитата(dxp @ Oct 15 2009, 06:41) *
Обоснуйте, пожалуйста. На примере.

function( a );
Скажите, пожалуйста, как в данном конкретном случае (С++) передается параметр 'a' по ссылке, или по значению?
Цитата
Каких ненужных имен? Что такое обязательно именованные структуры?

Тут ошибся sad.gif - редко на плюсах пишу - привиделось. Зато вспомнилось такое
Цитата
struct aaa {
const int aa;
};

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

Цитата
Так было несколько лет назад (5+). Но сегодня ситуация уже совсем иная. Платформ в embedded, для которых есть С и нет С++, по пальцам можно пересчитать.

Речь идет не о том, декларировано наличие какого-либо ПОДМНОЖЕСТВА C++ для embedded компилятора, а в том, насколько эти усеченные реализации СОВПАДАЮТ у разных компиляторов. Я вот относительно недавно замаялся один чужой C++ проект для банального x86 править под Watcom компилятор - плюнул и Visual Studio взгромоздил.

Цитата
Про возможности ООП. В последнем проекте пришлось разрабатывать GUI. Вообще не понимаю, как работать с GUI без возможностей наследования и полиморфизма. Как представлю, что все это пришлось бы реализовывать на голом С, так просто паника подкатывает. smile.gif

smile.gif О это да. По иронии судьбы мои первые сишные опыты были на C++. Только появился свежайший Turbo C++ V1.0 компилятор, свободная IBM PC/XT и... На спор с уже достаточно опытным сишным программистом наперегонки, и с выжиманием СКОРОСТИ начали писать псевдографическую оконную библиотеку для порграмматора и с дальнейшим ее развитием под терминал тестовой системы. Короче, зеленый совсем, но победил за пару недель вечерних работ тогда я smile.gif. Уж больно все классически идеально все сие на плюсы ложилось. В буквальном смысле компилятор думал и делал за программиста очень многое. Потом... потом правда спустя несколько лет выжимание всего и вся для работы на 4.7MHz (не путать с гигагерцами smile.gif ) XT привело к переводу ее-;t на 'C', к заметному использованию ASM...
И стал меня и 'C' в большинстве случаев очень даже устраивать.
kurtis
Цитата
Скажите, пожалуйста, как в данном конкретном случае (С++) передается параметр 'a' по ссылке, или по значению?

У меня есть куча строчек вида
Код
KOG PP2 (str_PP04, mPP2, OP_PP2, K_PP2, inSchpz.PP_status[1]);
Это передача параметра по ссылке при инициализации объекта. Мне уже легче, что не нужно каждый раз крякозяблу (&) ставить "для понятности". К тому-же ее можно случайно забыть поставить и тогда вместо адреса будет передаваться непонятно что, ну а дальше результат непредсказуем.
zltigo
Цитата(kurtis @ Oct 15 2009, 18:19) *
ну а дальше результат непредсказуем.

Не будет, контроль типов никто не отменял.
P.S.
Ну а о рассуждать "понятливости" с теми, кто переменные называет OP_PP2, K_PP2.... вообще не хочется sad.gif.
kurtis
Цитата(zltigo @ Oct 15 2009, 19:06) *
Ну а о рассуждать "понятливости" с теми, кто переменные называет OP_PP2, K_PP2.... вообще не хочется sad.gif.

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

Забыл упомянуть очень важный момент. Если передать параметр через ссылку, то с ней далее очень удобно работать. Если функция (или метод) достаточно большая, то можно элементарно забыть где-то поставить нужную звездочку и спокойно сделать операцию над указателем, тут уже никакой контроль типов не спасет.
zltigo
Цитата(kurtis @ Oct 15 2009, 19:39) *
могу ответить Вам точно так-же, если не знаете почему они так называются

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

мне безразлично один Вы такой или там вас целая фирма sad.gif.
Цитата
о с ней далее очень удобно работать

и заодно многочисленные дополнительные операции разименовывания не видны и совесть эмбеддера не мучают - тишь да гладь в плюсовом исходнике smile.gif
Сергей Борщ
Цитата(zltigo @ Oct 15 2009, 16:56) *
function( a );
Скажите, пожалуйста, как в данном конкретном случае (С++) передается параметр 'a' по ссылке, или по значению?
На самом деле в этой точке совершенно не важно, передается он по ссылке или по значению. Это важно внутри реализации function(), а там это известно и реализация пописана с учетом способа передачи.
zltigo
Цитата(Сергей Борщ @ Oct 16 2009, 02:51) *
На самом деле в этой точке совершенно не важно....

типа совершенно не важно, изменится-ли значение 'a' после вызова этой функции??? Боюсь,что лично для меня это слишком высокий уровень пофигизма абстракции smile.gif.
Сергей Борщ
Цитата(zltigo @ Oct 16 2009, 11:27) *
типа совершенно не важно, изменится-ли значение 'a' после вызова этой функции???
Передавая указатель вы получаете такую же неопределенность. Может изменить, а может и не изменить. Даже если указатель в параметре описан как указатель на константный объект - его можно внутри функции грубой силой привести к указателю на неконстантный.
Цитата(zltigo @ Oct 16 2009, 11:27) *
Боюсь,что лично для меня это слишком высокий уровень пофигизма абстракции smile.gif.
Ну, как горорил один мой бывший шеф, имеющий первое высшее образование - медицинское, "сдуру можно и х.. сломать".
zltigo
Цитата(Сергей Борщ @ Oct 16 2009, 12:20) *
Передавая указатель вы получаете такую же неопределенность. Может изменить, а может и не изменить.

Ну если пуститься в схоластические рассуждения, то дело В САМОМ ФАКТЕ ВОЗМОЖНОСТИ ИЗМЕНЕНИЯ в одном случае и гарантированной НЕ возможности в другом. Делать эти два случая неразличимыми - ДУРНО. О чем я собственно и написал в начале. К тому как что-либо, в том числе и передача по ссылке, реализовано Виртом надо относится с большим вниманием.
А так, да в принципе для обеспечения более строгой работы с объектом по ссылке, нежели через указатель вещь не бесполезная. Наверное кому-то поможет, хотя с точки зрения минимализма и универсализма достаточно указателей. Причем поскольку наличие ссылок не покрывает возможности указателей, то культуру работы с указателями по любому надо в себе воспитывать. Умение уверено обращаться с указателями, делает лично для меня наличие передачи параметра по ссылке не сильно привлекательной.
Сергей Борщ
Цитата(zltigo @ Oct 16 2009, 13:27) *
делает лично для меня
Ну вот она ключевая фраза. А мне не нравятся статические локальные переменные. Вот почему-то не нравятся. Но я же не утверждаю, что они - зло и лишняя сущность.
dxp
Цитата(zltigo @ Oct 16 2009, 15:27) *
типа совершенно не важно, изменится-ли значение 'a' после вызова этой функции??? Боюсь,что лично для меня это слишком высокий уровень пофигизма абстракции smile.gif.

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

void f(const int A& x) { ... }

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

Кстати, заметил, что в С-сообществе культура использования const как-то не очень развита. Очевидно, это происходит оттого, что сами по себе константы более накладны, и вместо них предпочитают использовать макросы препроцессора.
zltigo
Цитата(dxp @ Oct 17 2009, 10:21) *
Если для важно, чтобы объект не менялся....

Ну естествено, речь идет не о грубом варианте не изменения объекта никогда smile.gif (что само по себе вырожденный случай для ссылок), а о банальной заметности того важного факта, что в функция работает с собственно объектом и о том, что о возможных последствиями этого факта надо не забыть.
Цитата
Кстати, заметил, что в С-сообществе культура использования const как-то не очень развита.

Лично я использую достаточно широко, в том числе достаточно часто прикрываю const некоторые элементы структур - конечно, своеобразный костыль smile.gif по сравнению с возможностями С++ sad.gif.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.