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

Fri, 28 Jan 2005 12:41:42 +0300 Yuriy K wrote to Harry Zhurov:

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

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

YK> J.2.

Отписка. Меня интересует конкретный результат этого выражения на МК АВР.

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

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

YK> iso9899-c99.pdf

YK> 3.4.3 YK> 1 undefined behavior

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

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

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

int a, b, c; ... a = b + c;

Это порождает неопределенное поведение или нет?

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

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

Есть у меня. Только я когда надо несколько другой Стандарт листаю. Этот без надобности. Тем не менее, из него не понятно, что же имеем на практике. А практика, как известно, критерий истины. В конечном итоге практический результат доминирует надо всем. И хочется понять, что же опасного в выражении int a = ptr2 - ptr1;?

Reply to
Harry Zhurov
Loading thread data ...

Fri, 28 Jan 2005 12:34:06 +0300 Yuriy K wrote to Harry Zhurov:

[...]

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

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

Ты оставь это цитатный догматизм попам в церкви. Объясни rationale? Что означает означает термин "неопределенное поведение" вообще и как он прикладывается к конкретной платформе.

Reply to
Harry Zhurov
2005-01-29, Vladimir Vassilevsky snipped-for-privacy@fullnet.net пишет:

Нет, здесь вместо make - сам IDE. А создание bat-файла - не более чем способ исполнения команд. Подозреваю, что этот IDE для DOS, в этом все дело.

Reply to
Dmitry Fedorov
2005-01-29, Maxim Polyanskiy snipped-for-privacy@p12.f.n5020.z2.fidonet.org> пишет:

autoconf, automake ?

Системы генерации Makefile из чего-то другого - вполне нормальное явление. Разумеется, в этом случае объектом рассмотрения является исходник, из которого генерится Makefile, а сам Makefile - вместо промежуточного ассемблера, в который заглядывают только из любопытства или при его отладке.

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

Ну, у каждого свой круг общения....

Это ничего не меняет. Либо программист разбирается в применяемых средствах, либо ему не место в этом проекте, в лучшем случае.

Моя среда позволяет задать последовательность сборки, если это необходимо, как неотъемлемую часть программы. Твоя - видимо, нет.

Ничего, так как последовательность сборки осталась правильной. Надо уметь писать makefiles.

В документации на конкретную систему makefiles, применяемую в данном проекте. В моем случае его не надо изменять для добавления/удаления файлов при соблюдении некоторых разумных соглашений.

Чтобы узнать твой метод, раз мой никуда не годится.

Эти зависимости - не в голове. Они либо документированы либо автоматизированы. Ничего не вылезает. Надо уметь делать проекты, другого пути нет.

Reply to
Dmitry Fedorov

Hello Harry.

27 Jan 05 17:15, you wrote to Genadi Zawidowski:

HZ> то ip1 - ip2 не определено, что-ли? Вполне определено - конкретное HZ> число получится. Модуль этого числа указывает, сколько интов HZ> помещается в кусок памяти между адресуемыми переменными. Другое дело, HZ> что какого-то практического смысла в этом не видно.

Hет, не определено. потому что эта разница может просто не влезть в int на платформах, где void* -- 8 байт, а int -- 4 байта. Практически все 64-х битные платформы (Alpha, IA64, AMD64, Spacr64) именно таковы. А результат разницы указателей по стандарту -- int, а не long. Hу да, ну да, нынче и вовсе ptrdiff_t, конечно. Hо этот запрет не убрали.

Я сам удивился, когда узнал, но по стандарту можно проводить арифметические операции только с указателями внутри одного массива.

// Lev

Reply to
Lev Serebryakov

Hello Harry.

28 Jan 05 07:53, you wrote to Genadi Zawidowski:

HZ> Hо не будет ли правильным тогда сказать, что значение не "не HZ> определено", а зависит от реализации?

С точки зрения стандарта -- не определено. Стандарт ничего не знает про реализации. Т.е. "зависит от реализации" и "не определено" -- это синонимы фактически с точки зрения стандарта.

// Lev

Reply to
Lev Serebryakov

Sun Jan 30 2005 10:29, Harry Zhurov wrote to Yuriy K:

HZ>>> А если на том же AVR char* ip1; char* ip2;, то как? YK>> J.2. HZ> Отписка.

Определение.

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

В вине. Если у тебя есть желание спорить со стандартом - флаг в руки.

YK>> iso9899-c99.pdf

YK>> 3.4.3 YK>> 1 undefined behavior

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

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

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

HZ> int a, b, c; HZ> ... HZ> a = b + c;

HZ> Это порождает неопределенное поведение или нет?

RTFM.

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

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

HZ> Есть у меня. Только я когда надо несколько другой Стандарт листаю.

Какой?

HZ> Этот без надобности. Тем не менее, из него не понятно, что же имеем на HZ> практике. А практика, как известно, критерий истины. В конечном итоге HZ> практический результат доминирует надо всем. И хочется понять, что же HZ> опасного в выражении int a = ptr2 - ptr1;?

6.4.6 -> J.2 -> 3.4.3

WBR, Yuriy

Reply to
Yuriy K

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

если не можешь прочитать/написать Makefile -- как программист ты не существуешь. почему вдруг синтаксис Makеfile для тебя оказался дебильным ?

Reply to
Dmitry Ponyatov

Привет Leha!

27 Jan 05 11:11, Leha Bishletov писал All:

LB> unsigned long a[4]; LB> volatile unsigned int i; LB> void f() LB> { LB> i=(&(a[1]))-(&(a[0])); LB> }

То есть функция f() присваивает переменной i единицу.

LB> После компиляции (оптимизация выключена) получается: LB> .... LB> ldr r2, .L2 LB> mov r3, #1 <<<<<<<<<<<<<<<<<<<<< LB> str r3, [r2, #0] LB> .....

Логично, вполне правильный код. Какие претензии к выделенной строчке?

LB> Если немного изменить исходный код LB> i=(a+1)-(a); LB> то ни чего не изменится,

Опять логично. А почему что-то должно измениться? Раскрой скобки - этот код присваивает переменной i единицу.

LB> а если изменить так:

LB> i=((int)(&(a[1])))-((int)(&(a[0])));

LB> то получится:

LB> ldr r2, .L2 LB> mov r3, #4 <<<<<<<<<<<<<<<<<<<<<< LB> str r3, [r2, #0]

LB> Что кажется более правильным.

Более правильным чем что? AFAIK преобразование указателя к целому типу, которое в последнем примере применено, явлется машиннозависимым.

LB> Интересно, это gcc ошибается, или все же я чего-то не понимаю?

Где ты видишь ошибку?

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Чудо-йогурт Био. Чемпион среди какао.

Reply to
Alex Mogilnikov

Привет Harry!

27 Jan 05 17:15, Harry Zhurov писал Genadi Zawidowski:

HZ> А что, если

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

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

HZ> то ip1 - ip2 не определено, что-ли? Вполне определено - конкретное HZ> число получится.

Число-то оно всегда число, но не всегда осмысленное. К примеру, у MCS51 несколько разных адресных прстранств. Если ip1 указывает на объект во внутреннем ОЗУ, а ip2 - во внешнем, разность между ними даст целое число...

HZ> Модуль этого числа указывает, сколько интов HZ> помещается в кусок памяти между адресуемыми переменными.

...но это число ни о каком "сколько интов" не говорит. :)

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Сисоп спит - почта идет...

Reply to
Alex Mogilnikov

Hello Yuriy.

29 Jan 05 18:24, you wrote to Dmitry Fedorov:

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

Кодеров, кодеров. Все программисты слышали. И пользовались. Я не очень понимаю, как можно быть программистом и не автоматизировать билд. Автоматизировать полностью. А все IDE этого не позволяют. позволяют - мейк-файлы или теперь модный Ant/NAnt...

// Lev

Reply to
Lev Serebryakov

Hello, Harry! You wrote to Yuriy K on Sun, 30 Jan 2005 07:29:58 +0000 (UTC):

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

Ты будешь смеятся, но я года три сопровождал проект _не_ _понимая_ как собирается выходной имидж. Добрый мэйк три или четыре раза рекурсивно вызывал сам себя, изредка делая исключение для перла (авк им, видите-ли, не подходит). Разобраться в этом самомодифицирующемся монстре не было ни малейшей возможности. Один раз понадобилось добавить пару файлов - их пришлось прописывать в трёх разных местах этого чудесного мэйкфайла. Когда-то ходил по эхам исходник - десяток строк на си, которые после компиляции должны были породить программу, играющую в шахматы. Строки эти представляли собой кучку жутко запутанных макросов. Это, конечно, прикол, если программист попробует применить такое в реальной работе, то, скорее всего, он быстро останется без оной. А вот с мейком ситуация чуть ли не обратная. Может быть мэйк действительно провоцирует написание нечитабельных скриптов и трюкачество?

With best regards, Alexander Derazhne

Reply to
Alexander Derazhne

Привет Yuriy!

27 Jan 05 18:15, Yuriy K писал Dmitry Fedorov:

YK> Очень плохой метод.

YK> 1) Кто гарантирует последовательность линковки файлов?

Линкер.

YK> 2) Приличные программы не зависят от последовательности линковки.

Кто сказал? Если процессор начинает выполнение кода с адреса 0, ему заведомо не все равно, какой модуль будет первым. :)

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Программисты и программистки! Выше флаг промежуточного переноса!

Reply to
Alex Mogilnikov

Sun, 30 Jan 2005 15:22:50 +0300 Yuriy K wrote to Harry Zhurov:

HZ>> Отписка.

YK> Определение.

Я просил не цитаты метать - на это много ума не надо. Я просил объяснить по-человечески, своим словами, что скрывается за этими сухими фразами. Желательно с примерами... Правда, для объяснения требуется, чтобы объясняющий и сам понимал вопрос на достаточную глубину...

YK> В вине. Если у тебя есть желание спорить со стандартом - флаг в руки.

У меня есть желание понимать, чтО стоИт за тем или иным требованием Стандарта - чтобы осмысленно пользоваться (или не пользоваться) теми или иными средствами. И найти ответ на вопрос. Только от тебя этого не дождаться.

[...]

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

HZ>> int a, b, c; HZ>> ... HZ>> a = b + c;

HZ>> Это порождает неопределенное поведение или нет?

YK> RTFM.

Не знаешь. Я почему-то так и думал. Но теперь это уже не важно - с этим вопросом я разобрался и знаю, что означают термины "unspecified behaviour", "undefined behaviour" и "implementation-defined behaviour".

ПризнаЮ, мое разумение понятия "undefined behaviour" не вполне соответствовало истине - я полагал, что под этим скрывается только опасное (из-за непредсказуемости) поведение программы, каковое, например, может возникнуть из-за разыменовывания неинициализированного указателя, запись за границы массива, удаление уже удаленного объекта. На деле оказывается все несколько шире и под это понятие попадает весьма широкий класс действий. И далеко не все из них опасны. И далеко не все из них при реализации оказываются неопределенными.

Reply to
Harry Zhurov

Sun, 30 Jan 2005 16:52:52 +0300 Alex Mogilnikov wrote to Harry Zhurov:

HZ>> то ip1 - ip2 не определено, что-ли? Вполне определено - конкретное HZ>> число получится.

AM> Число-то оно всегда число, но не всегда осмысленное. К примеру, у MCS51 AM> несколько разных адресных прстранств. Если ip1 указывает на объект во AM> внутреннем ОЗУ, а ip2 - во внешнем, разность между ними даст целое число...

Про осмысленность речь не идет. Хотя кое-где оно будет вполне осмысленным.

HZ>> Модуль этого числа указывает, сколько интов HZ>> помещается в кусок памяти между адресуемыми переменными.

AM> ...но это число ни о каком "сколько интов" не говорит. :)

MSP430. Адресное пространство 64К. int'ы выравниваются по четным адресам (аппаратное требование).

int a = ptr1 - ptr2;

abs(a) - всегда будет указывать на то, сколько интов поместится между адресами в ptr1 и ptr2.

Reply to
Harry Zhurov

Привет Harry!

28 Jan 05 07:53, Harry Zhurov писал Dmitry Fedorov:

HZ> Хм. В приличных компиляторах для определения размеров секций HZ> имеются специальные средства. Hеужели в gcc этого нет?

Это как? Секцию же составляет линкер, и на этапе компиляции "угадать" ее размер невозможно. Вот ld действительно, имеет средства определить размер секции.

DF>> А вот для локальных объектов смысла нет никакого.

HZ> Hу почему же? Точно такой же хак - локальные объекты живут в HZ> стеке,

Hет. Локальные переменные могут иметь разный storage-class, например static. Да и автоматические переменные не обязаны размещаться в стеке. Hапример, IAR для MCS51 размещает их не в стеке (если только его специально об этом не попросить).

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Искать смысл - бессмысленно...

Reply to
Alex Mogilnikov

Привет Harry!

28 Jan 05 07:53, Harry Zhurov писал Yuriy K:

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

ISO/ IEC JTC1/SC22/WG14 N843 [...] 4. Conformance [...] Undefined behavior is otherwise indicated in this International Standard by the words ``undefined behavior'' or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ``behavior that is undefined''.

HZ> А про него, по ходу, правильнее сказать "зависит от реализации"?

3.11 [#1] implementation-defined behavior unspecified behavior where each implementation documents how the choice is made [...] [#1] unspecified behavior behavior where this International Standard provides two or more possibilities and imposes no requirements on which is chosen in any instance

AFAIK по обсуждаемому случаю в стандарте нет "two or more possibilities". Стало быть, именно undefined.

HZ> Про undefined там сказано только то, что если результат операции HZ> (вычитания адреса одного элемента массива из адреса другого элемента - HZ> т.е. тоже не наш случай) не представим типом ptrdiff_t, то поведение HZ> не определено. Хотя мне не понятно, почему - если я от одного целого HZ> (адрес - целое) отнял другое целое, то получил тоже какое-то целое.

Указатель - не адрес.

HZ> Про то, определено это _значение_ или не определено, обсуждаем, но HZ> почему тут _поведение-то_ неопределено? Hеопределенное поведение - это HZ> когда может произойти все, что угодно вплоть до падения программы. Hе HZ> понятно, как такое безобидное действие, как вычитание одного адреса из HZ> другого, может привести к каким-то негативным последствиям??! Речь HZ> ведь не идет об использовании результата!

Hу вот такие правила приняли, что согласно им имеет право:

[#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).

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Посетители должны общаться по сети.

Reply to
Alex Mogilnikov

Sun, 30 Jan 2005 14:00:05 +0000 (UTC) Alexander Derazhne wrote to Harry Zhurov:

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

AD> Ты будешь смеятся, но я года три сопровождал проект _не_ _понимая_ как AD> собирается выходной имидж. Добрый мэйк три или четыре раза рекурсивно AD> вызывал сам себя, изредка делая исключение для перла (авк им, видите-ли, не AD> подходит). Разобраться в этом самомодифицирующемся монстре не было ни AD> малейшей возможности. Один раз понадобилось добавить пару файлов - их AD> пришлось прописывать в трёх разных местах этого чудесного мэйкфайла.

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

Для того, чтобы проект развивался устойчиво, надо им управлять - те самые организационные мероприятия. Для того же make есть стандартные подходы, которые позволяют решить 99% задач. В конечном итоге makefile и make - это возможность задать цели и зависимости через явные и неявные правила. И ряд дополнительных средств - набор функций и макроподстановка. При разумном подходе все получается замечательно. Единственное, чего, имхо, не хватает - неплохо бы отладчик иметь. А может он есть, только мне не попался. :)

Reply to
Harry Zhurov

Sun, 30 Jan 2005 17:40:21 +0300 Alex Mogilnikov wrote to Harry Zhurov:

AM> 28 Jan 05 07:53, Harry Zhurov писал Dmitry Fedorov:

HZ>> Хм. В приличных компиляторах для определения размеров секций HZ>> имеются специальные средства. Hеужели в gcc этого нет?

AM> Это как? Секцию же составляет линкер, и на этапе компиляции "угадать" AM> ее размер невозможно. Вот ld действительно, имеет средства определить AM> размер секции.

IAR позволяет в исходном тексте на С/С++ ввести именованные сегменты (у него секции сегментами называются) и ссылаться на них (и на встроенные сегменты - там есть пачка встроенных для данных, кода). И размещать в сегментах объекты. Прямо в сорце. Это удобно. Сегменты можно задавать, например, с помощью прагм.

DF>>> А вот для локальных объектов смысла нет никакого.

HZ>> Hу почему же? Точно такой же хак - локальные объекты живут в HZ>> стеке,

AM> Hет. Локальные переменные могут иметь разный storage-class, например AM> static.

Ну, тогда еще надо вспомнить размещаемые в свободной памяти. :)

AM> Да и автоматические переменные не обязаны размещаться в стеке. Hапример, AM> IAR для MCS51 размещает их не в стеке (если только его специально об этом AM> не попросить).

Если ты возьмешь адрес локальной переменной (оператором &), то будь уверен, компилятор разместит эту переменную в стеке.

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.