Гость Опубликовано 24 февраля, 2002 Жалоба Опубликовано 24 февраля, 2002 Люди, подскажите, пжалста!!! Вот пример проги с void.ru: void function(int a, int b, int c) { char buffer1[5]; char buffer2[15]; int *ret; ret = buffer1 + 12; /* прога отлично "работает" на gcc-2.95.3 (под FreeBSD) и на kgcc-2.91.66 (egcs под Linux-2.4.16), но под gcc-2.96 */ // ret = buffer1 + 28; // <-- приходится делать так... (*ret) += 8; //(*ret) += 10; // и так void main() { int x; x = 0; function(1, 2, 3); x = 1; printf("%d\n",x); } В чем дело? Что еще запихивается в стек до buffer1, или там выравнивание проискодит по другому? Цитата
Гость Опубликовано 25 февраля, 2002 Жалоба Опубликовано 25 февраля, 2002 nu vo pervih, void main() --> eto ploho. pochemu? : smotri http://www.faqs.org/faqs/C-faq/faq/ vtoroe, ret eto ukazatel'. buffer1 --> eto massiv. buffer1 --> facticheski buffer1[0]; tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu ugodno. takim obrazom, ret = buffer1 + 12; zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). neudivitel'no shto inogda ret pokazivaet kuda to, a inogda i za predeli. otsyuda i SIGSEGV. krome togo, ret obyavlen ukazatelen typa int., a pokazivaet na char. navernoe hotelos' sdelat' shto-to typa: char buffer1[5]; char *ret = NULL; ret = &buffer1 + 12; odnako, 12 sovershenno ne garantiruet 12 elementov.) sovershenno verno bilo zamecheno, shto viravnivanie mozet proishodit.... pravilv'no bilo bi shto to typa: ret = &buffer1; ret += (12*sizeof(buffer1[0])); Цитата
Гость Опубликовано 25 февраля, 2002 Жалоба Опубликовано 25 февраля, 2002 > ret eto ukazatel'. Точнее в стеке хранится адрес возврата > buffer1 --> facticheski buffer1[0]; buffer1 == &buffer1[0] > tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu > ugodno. kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя это проверяется командой kgcc -S ex.c (получится асмовский код) А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт.... > takim obrazom, ret = buffer1 + 12; > zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл. > navernoe hotelos' sdelat' shto-to typa: > char buffer1[5]; > char *ret = NULL; > ret = &buffer1 + 12; 1) ret = buffer1 + 12; 2) тут действует стандартное преобразование типов. Фактически: buffer1 = buffer1 + 12; ret = buffer1; --------------------- Так все таки почему gcc-2.96 отводит "левое" кол-во памяти??? Цитата
Гость Опубликовано 25 февраля, 2002 Жалоба Опубликовано 25 февраля, 2002 > ret eto ukazatel'. Точнее в стеке хранится адрес возврата > buffer1 --> facticheski buffer1[0]; buffer1 == &buffer1[0] > tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu > ugodno. kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя это проверяется командой kgcc -S ex.c (получится асмовский код) А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт.... > takim obrazom, ret = buffer1 + 12; > zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл. > navernoe hotelos' sdelat' shto-to typa: > char buffer1[5]; > char *ret = NULL; > ret = &buffer1 + 12; 1) ret = buffer1 + 12; 2) тут действует стандартное преобразование типов. Фактически: buffer1 = buffer1 + 12; ret = buffer1; --------------------- Так все таки почему gcc-2.96 отводит "левое" кол-во памяти??? Цитата
Гость Опубликовано 25 февраля, 2002 Жалоба Опубликовано 25 февраля, 2002 > ret eto ukazatel'. Точнее в стеке хранится адрес возврата > buffer1 --> facticheski buffer1[0]; buffer1 == &buffer1[0] > tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu > ugodno. kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя это проверяется командой kgcc -S ex.c (получится асмовский код) А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт.... > takim obrazom, ret = buffer1 + 12; > zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл. > navernoe hotelos' sdelat' shto-to typa: > char buffer1[5]; > char *ret = NULL; > ret = &buffer1 + 12; 1) ret = buffer1 + 12; 2) тут действует стандартное преобразование типов. Фактически: buffer1 = buffer1 + 12; ret = buffer1; --------------------- Так все таки почему gcc-2.96 отводит "левое" кол-во памяти??? Цитата
Гость Опубликовано 25 февраля, 2002 Жалоба Опубликовано 25 февраля, 2002 в gdb набери help stack и не морочь людям голову Цитата
Гость Опубликовано 26 февраля, 2002 Жалоба Опубликовано 26 февраля, 2002 Вообще-то, чтобы получить return address в gcc есть __builtin_return_address..... А для того чтобы делать нелокальные переходы вообще-то лучше setjmp/longjmp Цитата
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.