Название: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 13, 2007, 07:00:06 Фрагмент программы:
Цитировать /* include */ #include "memory.h" #include "iostream.h" /* test enum */ enum testEnum { value1, value2, value3, value4 }; /* test struct */ struct testStruct { testEnum te; unsigned char flag; }; /* main program */ int main(int argc, char* argv[]) { testStruct A, B; int st; ........... ........... A.te = value1; A.flag = 1; B.te = value1; B.flag = 1; st = memcmp((void*)&A, (void*)&B, sizeof(A)); cout<<st<<endl; return 0; } /* end of program */ Результат выполнения программы: st = 1, т.е. А не равно B !!! Вопрос: Как такое может быть? Название: Re: Викторина на тему "Искусство программир Отправлено: Sochin от Март 13, 2007, 09:05:15 Вопрос: Как такое может быть? Такое может быть если двоичное представление экземпляров структур в памяти неидентично. Например, при выравнивании членов в памяти могут образовываться дыры, заполненные мусором. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 14, 2007, 11:11:10 В каком месте и сколько? конкретные цифры.
Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 14, 2007, 05:15:01 НУ? неужели никто не может посчитать?
Название: Re: Викторина на тему "Искусство программир Отправлено: Sochin от Март 14, 2007, 05:42:18 В каком месте и сколько? конкретные цифры. Как в анеке: "Это уже второй сложный вопрос!". ))) Если серьезно, то 1) В каком месте: ясное дело, что между полями структуры, так как члены, объявленные рядом друг с другом, компилятор не обязательно расположит в памяти вплотную друг к другу. Вот читаем книжку: Цитата: Страуструп Размер объекта структурного типа не обязательно равен сумме размеров всех его членов. Это происходит по той причине, что на многих машинах требуется размещать объекты определенных типов, только выравнивая их по некоторой зависящей от системы адресации границе (или просто потому, что работа при таком выравнивании будет более эффективной ). Типичный пример - это выравнивание целого по словной границе. В результате выравнивания могут появиться "дырки" в структуре. 2) Сколько - это уже третий сложный вопрос. И вопрос не языка С++, а конкретной его реализации, т.е. ответ зависит от платформы и компилятора, а не от текста твоей программы или стандарта С++. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 11:07:00 Цитата правильная, но все таки....
В каком месте и сколько? конкретные цифры. Для других структур показанный мной пример работает отлично и никогда никаких дыр не было!!!! И ничто не мешали сравнению структур по памяти. Но в этой структуре есть явная дыра. И ее необходимо увидеть. На мой взгляд пример очень интересный... Название: Re: Викторина на тему "Искусство программир Отправлено: Sochin от Март 15, 2007, 11:26:04 Цитата правильная, но все таки.... В каком месте и сколько? конкретные цифры. Для других структур показанный мной пример работает отлично и никогда никаких дыр не было!!!! И ничто не мешали сравнению структур по памяти. Но в этой структуре есть явная дыра. Явная-неявная...с точки зрения языка С++ нет никакой дыры. Дыры делает не язык, а компилятор. Еще раз: данный компилятор для конкретной плафтормы. Другой компилятор вполне может расположить иначе члены. С++ это не регламентирует и не ограничивает, насколько я понимаю. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 11:56:54 Sochin неправильно.
У кого нибудь есть еще варианты? Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 15, 2007, 12:17:11 Неправильно что?
Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 12:30:04 Цитировать с точки зрения языка С++ нет никакой дыры - ДАЦитировать Дыры делает не язык, а компилятор - ДаЦитировать С++ это не регламентирует и не ограничивает - неправильно, настраивает и ограничивает директивами препроцессора. Но для программиста это не отмазка. Программист должен знать какой код для его программы построит компилятор, ну я так считаю :) . У нас были случаи, когда приходилось бинарный код для контроллера открывать в дебаггере и смотреть асм код, т.к. на С все было написано без ошибок.Дыра есть )))) Лично я ее искал долго, 30 минут. А знающий человек подошел и сразу сказал где ошибка и точные цифры назвал. Я по дампу памяти сверил. Хотя можем об этом потом поспорить, когда ответ напечатаю, буду рад принять участие в споре :D Название: Re: Викторина на тему "Искусство программир Отправлено: Sochin от Март 15, 2007, 12:41:11 Цитировать С++ это не регламентирует и не ограничивает - неправильно, настраивает и ограничивает директивами препроцессора. Т.е. ты хочешь сказать, что стандарт С++ определяет некоторые директивы препроцессора, которые во всех реализациях языка для всех платформ позволяют четко задать в том числе и все параметры выравнивания членов структур в памяти? Я правильно тебя понял? Цитировать Но для программиста это не отмазка. Программист должен знать какой код для его программы построит компилятор, ну я так считаю :) . У нас были случаи, когда приходилось бинарный код для контроллера открывать в дебаггере и смотреть асм код, т.к. на С все было написано без ошибок. Дыра есть )))) Лично я ее искал долго, 30 минут. А знающий человек подошел и сразу сказал где ошибка и точные цифры назвал. Я по дампу памяти сверил. Ты определись для начала где дыра. В С++, в твоей программе или в дампе памяти. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 01:24:26 1. Да. Только наверное стандарт ANSI C, мне кажется что стандарт C++ так и не принят, есть только вариации к нему. Или уже принят? Хотя со стандартами у меня слабовато. Но такая возможность есть.
2. Хихик, дыра в дампе памяти структуры, которая создана компилятором из программного кода. А в программе ошибка, неучитывающая этого. 3. Мне кажется тут кроме нас никого больше нету ))) Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 15, 2007, 02:34:57 1. Да. Только наверное стандарт ANSI C, мне кажется что стандарт C++ так и не принят, есть только вариации к нему. Стандарт С++ принят после долгих мучительных лет работы по стандартизации в 1998 году. Стандарт ISO/IEC 14882:1998 Programming Language C++. Имеется исправленная версия стандарта ISO/IEC 14882:2003 Programming Language C++. Стандартная библиотека языка С++ целиком включает в себя стандартную библиотеку языка С, описанную в стандарте ISO/IEC 9899:1990 Programming Language C. Рабочая группа по стандартизации С++ продолжает свою работу. Ссылочка на сайт ISO (http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=38110&ICS1=35&ICS2=60&ICS3=) Ссылочка на сайт международной рабочей группы по стадартизации С++ (http://www.open-std.org/jtc1/sc22/wg21/) Цитировать Хотя со стандартами у меня слабовато. А зря. "Стандарты надо читать!" (с) (сами знаете какой самый-самый гуманнный преподаватель кафедры АСУ.) Было бы желание, в Сети можно бесплатно скачать последний доступный черновик стандарта. Окончательная версия правда платная. Цитировать Но такая возможность есть. В конкретной реализации (читай компиляторе) вполне возможно. В стандарте - врядли. Возможно разочарую, но скажу больше. Стандарт говорит вот о чем: представление, размер и диапазон фундаментальных типов зависит от реализации. У некоторых типов есть ограничения по выравниванию, которые также зависят от реализации. Стандарт определяет всего лишь минимальные требования для этих типов(см. файлы <climits> для целочисленных типов, <cfloat> для типов с плавающей точкой). В файле <limits> объявлены шаблоны для получения численнных характеристик всех фундаментальных типов. Круто, да? О каких конкретных цифрах может идти речь? )) Цитировать 2. Хихик, дыра в дампе памяти структуры, которая создана компилятором из программного кода. А в программе ошибка, неучитывающая этого. Ошибку в студию и тогда мы возможно подискутируем насколько это ошибка языка С++. Цитировать 3. Мне кажется тут кроме нас никого больше нету ))) Ыыы. Есть еще космос и еще кое-что. ))) Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 04:03:08 Ок, так и быть, раз уж тут мы с тобой вдвоем и больше никого нет.
Вобщем директива #pragma pack(n) устанавливает границы выравнивания для структур, объединений и классов. По умолчанию n=8 хотя может принимать значения 1, 2, 4, 8 и 16. Тут получается, что sizeof(enum) = 4 байта. sizeof(unsigned char) = 1 байт. sizeof(testStruct) = 8 байт ==> т.е. sizeof(enum) + sizeof(unsigned char) + 3 байта выравнивания до 8 | 1 2 3 4 | 5 | 6 7 8 | |**** **** **** **** | **** |**** **** **** | | enum | char | мусор | Вопрос номер два: какие строки необходимо добавить вместо "..........." чтобы структура А отличалась от В. Ответ: memset( (void*)&A, 0xff, sizeof(A)); memset( (void*)&B, 0xcc, sizeof(B)); PS спасибо за ссылки на стандарты. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 15, 2007, 06:17:58 ОК, прагма так прагма. Читаем стандарт:
Цитировать 16.6 Pragma directive A preprocessing directive of the form # pragma pp-tokensopt new-line causes the implementation to behave in an implementation-defined manner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any pragma that is not recognized by the implementation is ignored. Т.е. директива Pragma обрабатывается(и если обрабатывается, то как именно обрабатывается!) или не обрабатывается не зависит от твоей программы или от стандарта языка, а зависит только от реализации языка в конкретном компиляторе. Если конкретный компилятор не признает директиву #pragma pack(n), то он чихать на нее хотел и все равно выравняет члены как ему будет угодно. А если и признает, то не факт что будет выполнять именно выравнивание объектов, а может например отформатировать тебе винт. ))) И компилятор будет полностью прав, так как такое его поведение соответствует стандарту С++. )) Мораль? В этой задаче, если ты приводишь текст программы, а решение компиляторо-платформенно-зависимое, то необходимо указывать используемый компилятор/платформу. Я так думаю. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Alder от Март 15, 2007, 06:38:19 Перечитал я все это и согласен с Sochin - решение задачи есть зависимым от компилятора.
Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 06:40:44 уххххх..... ну чё я сказать могу? Твоя цитата относится ко всем директивам #pragma. А конкретно про #pragma pack ничего не сказано.Там только общие фразы и ничего конкретного.
я С реально использую и все мои задачи взяты реально из практики. Если исходить из твоей логики, тогда мой пример не имеет решения, и предопределить действие компилятора вообще невозможно? ерунда какая-то. Что на практике проверено, то факт, а то что на бумаге написано - то фигня. Вот мое мнение. Компиляторы: VC, gcc, Tornado, bc, STL для Siemens - все нормально поддерживают pragma pack и никто из них пока не возмущался. А эта директива используется чтобы выравнять размер структур при передаче данных от платформы к платформе, часто используется при передаче данных в сетях. Единственная зависимость от компилятора и от платформы: установленное значение по умолчанию для #pragma pack Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 06:45:16 Если бы я сразу указал в начале программы #pragma pack(8 ) то все бы сразу поняли в чем дело. Это ж совсем не интересно )))))
А указать место мусора в структуре тоже было несложно. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Storm от Март 15, 2007, 06:55:55 а какой компилятор С ты используешь для какого процессора?
Для тех процов, для которых пишу я на С,этот код даст ответ 0. ЗЫ: Потому что там выравнивание побайтовое ;) и оперативки всего 512 байт ;) Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 07:04:34 Storm может и побайтовое, если контроллер. )))))))))
Вообще-то чтобы получилось 1 или -1, надо предварительно заполнить структуру (и мусор в ней) какими-то значениями, например командой memset. По стандарту в С++ все создаваемые объекты равны 0 или заполнены 0х00. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 15, 2007, 07:17:25 уххххх..... ну чё я сказать могу? Твоя цитата относится ко всем директивам #pragma. А конкретно про #pragma pack ничего не сказано.Там только общие фразы и ничего конкретного. Все там конкретно: семантика конкретной прагмы зависит от реализации в конкретном компиляторе. Т.е. два компилятора, соответствующих стандарту С++ могут ее по разному интерпретировать и реагировать на нее. Цитировать я С реально использую и все мои задачи взяты реально из практики. Если исходить из твоей логики, тогда мой пример не имеет решения, и предопределить действие компилятора вообще невозможно? ерунда какая-то. Возможно узнать действия компилятора. Для этого нужно узнать какие прагмы в данном компиляторе поддерживаются и что делают. )) Цитировать Что на практике проверено, то факт, а то что на бумаге написано - то фигня. Вот мое мнение. Это мнение студента-первокурсника «но программа ведь компилится и работает!!!» в ответ на замечание преподавателя о наличии логической ошибки в программе. )) Цитировать Единственная зависимость от компилятора и от платформы: установленное значение по умолчанию для #pragma pack Компилятор С++ по стандарту вообще может не поддерживать твою прагму или придавать ей другой смысл. Но если стандарт - это не авторитетный источник, тогда вопрос закрываю... А указать место мусора в структуре тоже было несложно. Ты уверен в том что мусор будет в указанном тобой месте и в указанном тобой размере на любой из существующих или будущих платформах, для которой можно создать компилятор С++? Или вообще в наличии мусора как такового на любой платформе? Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 07:28:31 Да, стандарт - это не авторитетный источник.
привели конкретный пример платформы или компилятора, где не работает #pragma pack Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 15, 2007, 07:35:08 Да, стандарт - это не авторитетный источник. Все вопросов больше не имею. Цитировать привели конкретный пример платформы или компилятора, где не работает #pragma pack Товарищ, язык С++ - это язык программирования, который описан в стандарте, а не компилятор, уж прости за то что приходится повторять очевидные казалось бы вещи. Есть компиляторы, нету компиляторов, поддерживают они стандарт или нет, вне зависимости от этого если ты пишешь в условии задачи про исходник на С++ без указания компилятора, то это подразумевает, что решение доступно стандартными средствами, а все нестандартные фокусы неприменимы. Иначе твоя задача несостоятельна. Заметь, даже при условии, что я такой платформы или компилятора могу и не знать. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 15, 2007, 08:10:29 Sochin ты меня замучал своими придирками. Нормальная задача, нормальные требования и нормальный ответ. Все твои слова - вода. Я, в отличие от тебя, привел конкретную реализацию, конкретный ответ и конкретные компиляторы где все это работает.
Если ты уверен что я ошибаюсь, тогда приведи конкретный пример, как Storm. Нестандартных фокусов тут нет. Если ты не сталкивался с такой проблемой на практике, это не значит что я тут шаманю. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Storm от Март 15, 2007, 10:20:27 Storm может и побайтовое, если контроллер. ))))))))) Именно, AVR фирмы Atmel и MicroCHIP PIC. в них считаешь каждый бит и раскидываться на выравнивание непозволительная роскошь.Вообще-то чтобы получилось 1 или -1, надо предварительно заполнить структуру (и мусор в ней) какими-то значениями, например командой memset. По стандарту в С++ все создаваемые объекты равны 0 или заполнены 0х00. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 16, 2007, 11:38:44 Sochin ты меня замучал своими придирками. Нормальная задача, нормальные требования и нормальный ответ. Все твои слова - вода. Придирки? Вода? Цитаты пожалуйста. Куда уж конкретнее - #pragma pack не описана в стандарте языка, т.е. она не является стандартной для С++. Ее употребление - это нестандартная фича. Если мы говорим о конретном компиляторе - нет вопросов. Но ты настаиваешь на том, чтобы не указывать конкретную реализацию. А если мы говорим о языке в целом, то твой ответ на твою же задачу не является верным для общего случая. Вода? Цитировать Я, в отличие от тебя, привел конкретную реализацию, конкретный ответ и конкретные компиляторы где все это работает. Да нет проблем, работает и хорошо, я ж не говорю что не работает. Но я, похоже что в отличие от тебя, понимаю что такое язык и стандарт и что такое компилятор и нестандартные фичи. Цитировать Если ты уверен что я ошибаюсь, тогда приведи конкретный пример, как Storm. Компилятор назвать? Пожалуйста, в качестве примера IBM Rational Apex® C/C++ compiler (http://www-1.ibm.com/support/docview.wss?rs=980&context=SSSGW8&dc=DB520&uid=swg21216846&loc=en_US&cs=UTF-8&lang=en&rss=ct980rational) Вот посмотри, что пишут ребята из IBM (понимаю, что для тебя это возможно полная туфта, также как и стандарт языка, но все же): Цитировать C/C++ programmers often rely upon '#pragma pack' to remove padding between structure fields. However, this pragma has many pitfalls and it is not supported in the IBM Rational Apex® C/C++ compiler. There are some reasons not to use pragma pack: [1] It is implementation defined (as with all pragmas). Some processors have the instruction set to support non-aligned memory whereas others do not. [2] The syntax of pragma pack varies across implementations. 'pragma pack (n)' is the most common syntax for setting a particular packing alignment, but implementations vary in how to tell the compiler reset to the default alignment. Sometimes it's 'pragma pack (0)' while other times it's 'pragma pack ()'. Plus there are the 'push' and 'pop' derivatives offered by some vendors. In summary, the pragma is not portable. [3] pragma pack is stand-alone and affects all following declarations until the next pragma pack or the end of the compilation unit. Therefore, it is very easy to apply packing to structures where it is not wanted. [4] pragma pack specifies a *maximum* alignment. Thus, 'pragma pack (2)' followed by a structure of chars could give you either (i) each char packed into a byte or (ii) each char packed into a word. You won't know without debugging the code. Цитировать Нестандартных фокусов тут нет. Если ты не сталкивался с такой проблемой на практике, это не значит что я тут шаманю. Ой я тебя умоляю. Твой ответ не соответствует стандарту С++. Если ты не уважаешь стандарты, это другой вопрос. Менее нестандартным (с точки зрения стандарта С++ конечно, а то может у тебя другое понимание «стандартности/нестандартности») он от этого не становится. И я тут ни при чем. Все вопросы - в комитет по стандартизации. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: vimmax от Март 16, 2007, 12:30:21 Отлично! IBM -> http://www-1.ibm.com/support/ авторитетный для меня источник. Хорошая статья.
1. Теперь согласен, #pragma pack работает не на всех компиляторах. Цитировать С++ это не регламентирует и не ограничивает В данной статье отлично показано как изменить расположение членов структуры в памяти используя С++.2. Специалисты IBM отлично умеют расчитывать дыры в структурах и их конкретный размер. Это не случайный процесс, а четко определенный, его можно изучить и научится расчитывать самому. 3. Мой пример показывает, что необходимо хотябы примерно прикидывать расположение объектов в памяти и исключать подобные ошибки еще на этапе программирования. 4. Я думаю надо заканчивать эту дискуссию. На твое следующее сообщение отвечать не буду. ДА, забыл, Sochin +1 за ссылку на статью. Название: Re: Викторина на тему "Искусство программирования" (задача 4) Отправлено: Sochin от Март 16, 2007, 12:44:42 Цитировать С++ это не регламентирует и не ограничивает В данной статье отлично показано как изменить расположение членов структуры в памяти используя С++.Хе-хе. Цитируемое тобой замечание касалось конкретно твоего примера простой структуры без битовых полей. )) З.Ы. До встречи в очередной дискуссии. Закрывай тему. ))) |