Ошибка в вычислениях адресов у GCC ?

Fri Jan 28 2005 07:53, Harry Zhurov wrote to Leha Bishletov:

HZ> int Array[N];

HZ> Array[3] = 5;

HZ> но если написать:

HZ> int* p;

Забыл присвоить начальное значение. p = Array;

HZ> p[3] = 5;

HZ> то получишь, afair, неопределенное поведение.

Hет. Это по определению полностью эквивалентно Array[3] = 5;

iso9899-c99.pdf ...

6.5.2.1 Array subscripting ... The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). ...

WBR, Yuriy

Reply to
Yuriy K
Loading thread data ...

Fri Jan 28 2005 07:53, Harry Zhurov wrote to Yuriy K:

GZ>>>> "по стандарту" результат таких выражений определен, если сравниваются GZ>>>> или вычитаются адреса элементов одного массива между собой.

HZ>>> А что, если

HZ>>> extern int i1; HZ>>> extern int i2;

HZ>>> ... HZ>>> ip1 = &i1; HZ>>> ip2 = &i2;

HZ>>> то ip1 - ip2 не определено, что-ли?

YK>> Hе определено.

YK>> iso9899-c99.pdf: YK>> ... YK>> 6.5.6 Additive operators YK>> ... YK>> 9 When two pointers are subtracted, both shall point to elements of the YK>> same array object, or one past the last element of the array object; YK>> the result is the difference of the subscripts of the two array YK>> elements. ...

HZ> И где тут английским по белому написано, что _не_ _определено_? HZ> Где слово undefined?

iso9899-c99.pdf: ... J.2 Undefined behavior

1 The behavior is undefined in the following circumstances: ...

- Pointers that do not point into, or just beyond, the same array object are subtracted (6.5.6). ...

WBR, Yuriy

Reply to
Yuriy K
27-Jan-05 14:15 Harry Zhurov wrote to Genadi Zawidowski:

HZ> А что, если HZ> extern int i1; HZ> extern int i2; HZ> ... HZ> ip1 = &i1; HZ> ip2 = &i2;

HZ> то ip1 - ip2 не определено, что-ли? Не определено.

HZ> Вполне определено - конкретное число HZ> получится. Модуль этого числа указывает, сколько интов помещается в HZ> кусок HZ> памяти между адресуемыми переменными. Другое дело, что какого-то практического HZ> смысла в этом не видно. Про некратность разницы адресов размеру int уже сказали. На том же AVR между этими двумя интами влезет какой-то char и приплыли.

Вариант два - адреса far на архитектуре x86, состоят из сегмента и смещения. Ну именно на 8086 ещё можно подсуетиться и посчитать, а в защищённом режиме? Когда там сегменты - это не адреса?

wbr,

Reply to
Oleksandr Redchuk

Fri, 28 Jan 2005 08:16:58 +0300 Yuriy K wrote to Harry Zhurov:

HZ>> int Array[N];

HZ>> Array[3] = 5;

HZ>> но если написать:

HZ>> int* p;

YK> Забыл присвоить начальное значение. YK> p = Array;

Ничего я тут не забыл! Цель этого примера - продемонстрировать разницу между массивом и указателем! Только и всего. Или ты тоже будешь утверждать, что массив и указатель есть одно и то же?

HZ>> p[3] = 5;

HZ>> то получишь, afair, неопределенное поведение.

YK> Hет. Это по определению полностью эквивалентно YK> Array[3] = 5;

Блин, ты сообщение-то внимательно читал? Не надо выдергивать из контекста! Контекст был в первом случае "int Array[N]", во втором "int* p". И речь шла не про синтаксис адресации, а про то, что во втором случае значение прописывается по неопределенному адресу - вот это уж точно будет неопределенное поведение!

Reply to
Harry Zhurov

Fri, 28 Jan 2005 05:34:39 +0000 (UTC) Oleksandr Redchuk wrote to "Harry Zhurov" snipped-for-privacy@online.nsk.su>:

[...]

HZ>> то ip1 - ip2 не определено, что-ли? OR> Не определено.

HZ>> Вполне определено - конкретное число HZ>> получится. Модуль этого числа указывает, сколько интов помещается в HZ>> кусок HZ>> памяти между адресуемыми переменными. Другое дело, что какого-то HZ>> практического смысла в этом не видно. OR> Про некратность разницы адресов размеру int уже сказали. На том же AVR OR> между этими двумя интами влезет какой-то char и приплыли.

А если на том же AVR char* ip1; char* ip2;, то как?

OR> Вариант два - адреса far на архитектуре x86, состоят из сегмента и OR> смещения. Ну именно на 8086 ещё можно подсуетиться и посчитать, а OR> в защищённом режиме? Когда там сегменты - это не адреса?

Если на одной платформе нельзя предсказать, а на другой можно, то это как называется? Неопределенное - это когда ни на одной платформе нельзя предсказать? Или хотя бы на одной? А зависящее от реализации - это когда зная конкретную платформу, можно предсказать? Или надо, чтобы это можно было предсказать для любой конкретной платформы, а если есть хотя бы одна, для которой нельзя, то тогда это undefined behaviour, а не implementation-defined? Где истина?

И потом, одно дело неопределенное поведение [программы], другое - неопределенное значение результата выражения. Это, мне кажется, несколько разные вещи.

Reply to
Harry Zhurov

Fri Jan 28 2005 10:58, Harry Zhurov wrote to Yuriy K: HZ> [...]

HZ>>> И где тут английским по белому написано, что _не_ _определено_? HZ>>> Где слово undefined?

YK>> iso9899-c99.pdf: YK>> ... YK>> J.2 Undefined behavior

YK>> 1 The behavior is undefined in the following circumstances: YK>> ... YK>> - Pointers that do not point into, or just beyond, the same array object YK>> are subtracted (6.5.6). YK>> ...

HZ> Hе можешь пояснить на примере, к чему это приводит? Какой механизм HZ> прихода к неопределенному поведению при выполнении выражения "int a = pi1 HZ> - pi2;"? Hапример, на AVR

Еще раз. В _стандарте_ написано, что поведение _не_определено. Механизм, причины и результаты не имеют ни малейшего значения.

WBR, Yuriy

Reply to
Yuriy K

Fri Jan 28 2005 10:58, Harry Zhurov wrote to Oleksandr Redchuk:

HZ>>> то ip1 - ip2 не определено, что-ли? OR>> Hе определено.

HZ>>> Вполне определено - конкретное число HZ>>> получится. Модуль этого числа указывает, сколько интов помещается в HZ>>> кусок HZ>>> памяти между адресуемыми переменными. Другое дело, что какого-то HZ>>> практического смысла в этом не видно. OR>> Про некратность разницы адресов размеру int уже сказали. Hа том же AVR OR>> между этими двумя интами влезет какой-то char и приплыли.

HZ> А если на том же AVR char* ip1; char* ip2;, то как?

J.2.

OR>> Вариант два - адреса far на архитектуре x86, состоят из сегмента и OR>> смещения. Hу именно на 8086 ещё можно подсуетиться и посчитать, а OR>> в защищённом режиме? Когда там сегменты - это не адреса?

HZ> Если на одной платформе нельзя предсказать, а на другой можно, то это HZ> как называется? Hеопределенное - это когда ни на одной платформе нельзя HZ> предсказать? Или хотя бы на одной? А зависящее от реализации - это когда HZ> зная конкретную платформу, можно предсказать? Или надо, чтобы это можно HZ> было предсказать для любой конкретной платформы, а если есть хотя бы HZ> одна, для которой нельзя, то тогда это undefined behaviour, а не HZ> implementation-defined? Где истина?

iso9899-c99.pdf

3.4.3 1 undefined behavior

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

3 EXAMPLE An example of undefined behavior is the behavior on integer overflow.

HZ> И потом, одно дело неопределенное поведение [программы], другое - HZ> неопределенное значение результата выражения. Это, мне кажется, несколько HZ> разные вещи.

Все расписано. Тебе iso9899-c99.pdf выслать?

WBR, Yuriy

Reply to
Yuriy K
2005-01-28, Harry Zhurov snipped-for-privacy@online.nsk.su> пишет:

Нет. Какие это средства в приличных компиляторах? Очередное нестандартное расширение? В gcc это достигается неспециальным расширением.

Описанное выше - не хак, а совершенно законный механизм, разве что отсутсвующий в языке Си.

А вот этого - никто не обещал.

Секции - гораздо более переносимый и гарантированный от изменений механизм, чем размещение стека.

Reply to
Dmitry Fedorov
2005-01-27, Yuriy K snipped-for-privacy@taekwondo.co.nz> пишет:

Программист. Тот же, что пишет программу. Это его святая обязанность.

RTFM ld. Он "однопроходный" без специальных ключей. Фича.

Ты не понял? Я говорил как раз о секциях. Но в стандарт языка Си этот механизм не входит, всегда - только нестандартными расширениями.

Как узнать адреса начала и конца секции средствами языка Си? Я описал способ.

Reply to
Dmitry Fedorov

Fri Jan 28 2005 14:49, Dmitry Fedorov wrote to Yuriy K:

DF> Программист. Тот же, что пишет программу. Это его святая обязанность.

1) Hаличие makefile не обязательно. 2) Может генерироваться средствами среды. 3) Где в программе написаны указания программисту, в каком порядке линковать файлы.

DF> RTFM ld. Он "однопроходный" без специальных ключей. Фича.

Дык. Глюкодром и ламерство.

"Стандартный" не в смысле "описанный в стандарте", а в смысле "наиболее удобный и правильный".

DF> Ты не понял? Я говорил как раз о секциях. DF> Hо в стандарт языка Си этот механизм не входит, всегда - только DF> нестандартными расширениями.

Makefile в стандарт языка не входит. Особенности линкера и последовательность линковки в стандарт языка не входит. Память не обязана быть линейной и непрерывной. Управление размещением памяти в стандарт языка не входит.

Поэтому

DF> Как узнать адреса начала и конца секции средствами языка Си?

Hикак.

DF> Я описал способ.

Hет. Ты закладываешься на последовательность линковки, не описываемую средствами языка С.

WBR, Yuriy

Reply to
Yuriy K

Fri, 28 Jan 2005 11:49:18 +0000 (UTC) Dmitry Fedorov wrote to Harry Zhurov:

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

DF> Нет. Какие это средства в приличных компиляторах? DF> Очередное нестандартное расширение?

Да. А как ты хотел? Требования по конкретному размещению объектов со стороны пользователя сами по себе нестандартны, поэтому и средства для этого нестандартны. Что-то мне не кажется, что реализация нестандартного требования путем использования стандартных средств нестандартным способом лучше, чем специальное нестандартное средство. А геморроя больше.

[...]

DF> А вот этого - никто не обещал.

Т.е. может быть "дырявый" стек? Например?

DF> Секции - гораздо более переносимый и гарантированный от изменений механизм, DF> чем размещение стека.

С чего это? Насколько я ничего не понимаю, и то, и другое не входят в понятия языка.

Reply to
Harry Zhurov

Hello, Harry Zhurov !

Его в аппаратном виде может вовсе не быть.

С уважением, Дима Орлов.

Reply to
Dima Orlov
2005-01-28, Yuriy K snipped-for-privacy@taekwondo.co.nz> пишет:

Хоть какое средство автоматизации сборки необходимо.

Может. Но это ничего не меняет - изволь иметь средства указания среде.

Не программисту дают указания, а программист дает указания. Makefile или его аналог - часть программы.

Цитата:

Мало ли чего в стандарт языка не входит и достигается внешними средствами.

А секция обязана быть линейной и непрерывной?

Так опиши свой способ, в рамках языка Си.

Reply to
Dmitry Fedorov
2005-01-28, Harry Zhurov snipped-for-privacy@online.nsk.su> пишет:

Те средства - тоже нестандартны.

Неважно. Разность адресов статических символов имеет иногда какой-то смысл. Разность адресов автоматических переменных - нет.

Не входит. Но "гораздо более переносимы".

Reply to
Dmitry Fedorov

Sat Jan 29 2005 14:48, Dmitry Fedorov wrote to Yuriy K:

IDE, например.

formatting link
- где в IDE описана последовательность линковки?

DF> Hе программисту дают указания, а программист дает указания. DF> Makefile или его аналог - часть программы.

Программист уволился, наняли другого. Откуда он знает требуемую последовательность линковки?

Как опишешь, так и будет.

Hе существует. Читайте стандарты.

P.S. Результаты работы "программистов" пишущих программы, зависящие от последовательности линковки, мне уже приходилость переделывать...

WBR, Yuriy

Reply to
Yuriy K
2005-01-29, Yuriy K snipped-for-privacy@taekwondo.co.nz> пишет:

У нас с тобой разные понятия о среде.

Это проблема твоей IDE.

Последовательность записана в Makefile. Пользователю мakefile знать об этом не обязательно - оно работает (собирается) и без этого знания.

Я пользуюсь стандартными секциями, определеннымы в скриптах линкера для данной платформы. Они непрерывны. Или я определяю секции линейными и непрерывными. Как хочу.

Ф-фух! Я в курсе, что в языке Си этих средств нет. Значит, используются внешние средства. В данном случае это линкер и пара файлов на ассемблере, вместо которых можно использовать расширение языка, позволяющее помещать объект в заданную секцию.

Что неудивительно, для пользующихся IDE.

Reply to
Dmitry Fedorov

Sat Jan 29 2005 18:09, Dmitry Fedorov wrote to Yuriy K:

1) Минимум 90% программистов про makefile не слышали.

2) Программистов бывает больше одного.

DF> У нас с тобой разные понятия о среде.

Безусловно.

DF> Это проблема твоей IDE.

Конструктивного ответа не будет?

DF> Последовательность записана в Makefile. DF> Пользователю мakefile знать об этом не обязательно - оно работает DF> (собирается) и без этого знания.

Добавили/удалили пару файлов. Что делать? Где описано, как изменять makefile? Откуда об этом узнает новый человек?

Hе обязательно. Платформы бывают разные. Память бывает с дырками, может состоять из нескольких кусков.

DF> Или я определяю секции линейными и непрерывными. Как хочу.

Придется вводить много разных секций для кода. Исключительно неудобно.

Тогда зачем спрашиваешь?

------------- Пока проект маленький и разрабатывается одним незаменимым человеком можно писать что угодно и как угодно, лишь бы человек был хороший. :)

Когда проект побольше, рограммистов несколько, они приходят и уходят, все эти левые зависимости тут же вылезают боком.

WBR, Yuriy

Reply to
Yuriy K

Hello, Dmitry!

Пят Янв 28 2005, Dmitry Fedorov писал к Yuriy K по поводу "Re: Ошибка в вычислениях адресов у GCC ?." >> Кто создает makefile? DF> Программист. Тот же, что пишет программу. Это его святая обязанность. Я тоже так думал, пока не увидел makefile размером в 2.1 мегабайта. После детального просмотра выяснилось, что 99.9% этого файла было генерированно каким-то скриптом который прошелся по исходнику ;) Весело бы быдо посмотреть на программиста который подобное писал ручками.

WBR! Maxim Polyanskiy.

Reply to
Maxim Polyanskiy

Sat Jan 29 2005 23:20, Maxim Polyanskiy wrote to Dmitry Fedorov:

MP> Я тоже так думал, пока не увидел makefile размером в 2.1 мегабайта. После MP> детального просмотра выяснилось, что 99.9% этого файла было генерированно MP> каким-то скриптом который прошелся по исходнику

Есть такой весьма популярный Cosmic C, так вот в нем IDE автоматически создает bat-файл, который запускает компилер, линкер и все прочее с нужными опциями. Вот до чего доходит нелюбовь людей к make из-за его дебильного синтаксиса.

VLV

"Быть честным - лучший способ оставаться бедным" (c) Hаполеон Бонапарт

Reply to
Vladimir Vassilevsky

Sat, 29 Jan 2005 18:24:52 +0300 Yuriy K wrote to Dmitry Fedorov:

DF>>>>>> Программист. Тот же, что пишет программу. Это его святая

YK> 1) Минимум 90% программистов про makefile не слышали.

Это, извини, чушь! Даже в этой эхе, где не программисты собрались, большинство слышало про makefile и знает, что это такое - эта техника сборки уже неоднократно обсуждалась за последние несколько лет. А если пойти в программерскую эху, то там про makefile могут не знать только полные новички.

Вот если для тебя это откровение, то не надо на других прикладывать свой опыт.

YK> 2) Программистов бывает больше одного.

И что? Похоже, что в твоем окружении собрались программисты из п. 1).

DF>>>> Хоть какое средство автоматизации сборки необходимо.

Приличные IDE умеют генерить makefile для сборки с помощью make (кому это удобно).

DF>>>> Может. Hо это ничего не меняет - изволь иметь средства указания

DF>> Это проблема твоей IDE.

YK> Конструктивного ответа не будет?

Я тоже не пользуюсь IDE (хоть IAR, хоть CCS), ибо ацтой! А пользуюсь именно make (и хорошим программерским редактором). А IDE годится только в роли отладчика (исключительно потому, что отладчик в нее встроен).

DF>>>> Hе программисту дают указания, а программист дает указания. DF>>>> Makefile или его аналог - часть программы.

Если этот другой не в состоянии разобраться с makefile, который собирает проект, то с собственно программой ему будет разобраться вряд ли возможно, т.к. сама программа, как правило, гораздо сложнее скрипта сборки.

DF>> Последовательность записана в Makefile. DF>> Пользователю мakefile знать об этом не обязательно - оно работает DF>> (собирается) и без этого знания.

YK> Добавили/удалили пару файлов. Что делать? Где описано, как изменять YK> makefile? Откуда об этом узнает новый человек?

make надо уметь пользоваться. Как и уметь пользоваться IDE. Почему-то у тебя не вызывает вопроса, как этот другой чел будет разбираться с IDE, ее окошками, опциями, установками... А вдруг не разберется?!..

А что значит "линейной"? Память - это не функция из математики.

[...]

YK> Hе обязательно. Платформы бывают разные. Память бывает с дырками, YK> может состоять из нескольких кусков.

И что мешает целостный кусок затолкать в секцию? Или разбить на несколько секций? Каждая такая секция будет непрерывной.

DF>> Или я определяю секции линейными и непрерывными. Как хочу.

YK> Придется вводить много разных секций для кода. Исключительно неудобно.

Нормальный, широкоиспользуемый, где надо, подход. Если он не нужен тебе на AVR или другом МК, то не надо обобщать - есть платформы, где это необходимо и удобно.

[...]

YK> ------------- YK> Пока проект маленький и разрабатывается одним незаменимым человеком можно YK> писать что угодно и как угодно, лишь бы человек был хороший. :)

YK> Когда проект побольше, рограммистов несколько, они приходят и уходят, YK> все эти левые зависимости тут же вылезают боком.

Большие, сложные проекты всегда сложнее маленьких и простых. Коллективная разработка обычно сложнее индивидуальной, т.к. помимо технических вопросов вылезают еще и организационные, которые не поддаются автоматизации. Тут ты Америки не открыл. Но к IDE или make все это имеет весьма опосредованное отношение. И единственный способ держать процесс разработки под контролем - это создание и поддержание комплекса _организационных_ мер! Сюда могут входить перечень стилей кодирования (оформление исходников, правила именования и т.д.), правила документирования как программ, так и рабочего окружения и т.д. И самое главное - грамотный подбор кадров, т.к. "Кадры решают все!" (с) угадай чей.

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

Reply to
Harry Zhurov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.