|
|
|||||||||||
[Задача] Очередной пример трудноуловимой ошибки17.02.2012, 20:24. Показов 2606. Ответов 16
Метки задачи от evg (Все метки)
Задача возникла на основе реальной ошибки на большой задаче, которую искали довольно-таки долго. Чтобы суть задачи осталась, но сам тестовый пример не был излишне громоздким, пришлось его несколько подсократить и привести в несколько другой вид, чем он был в нашем случае. Пример содержит внутри себя ошибку. Из-за специфичности ошибки накладываю ограничения на то, где и как запускать пример:
Без этих ограничений пришлось бы вырезать большой фрагмент кода и маскировать его дополнительными фрагментами кода, которые бы прятали ошибку, не вызывая при этом предупреждений при компиляции Вопрос простой: объяснить поведение программы ВНИМАНИЕ! Тем, кто запускает программу вне указанных ограничений, огромная просьба не писать ничего в теме а-ля "а у меня тут под MSVS выдаётся такое-то предупреждение, что бы это значило?" (а лучше вообще ничего не пишите). Задача из разряда "найти ошибку в программе", а подобными вопросами вы попросту лишаете возможности хорошо подумать тех, кому задача покажется интересной. И ещё одна традиционная просьба: прячьте под cut'ами свои предположения и размышления (из тех же соображений).
9
|
|||||||||||
| 17.02.2012, 20:24 | |
|
Ответы с готовыми решениями:
16
Очередной неработающий пример из книги Шлее Пример из книги выдает ошибки Пример с учебника выдаёт ошибки |
|
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
|
|
| 17.02.2012, 20:57 | |
|
по рекомендации ТС
Ну в этом примере попытка использовать переменную вне блока, в котором она объявлена, бросается в глаза сразу, а вот почему собирается понять получается далеко не так быстро
Интересно, каким образом удалось в реальном коде заткнуть варнинги?
0
|
|
|
|
|
| 17.02.2012, 21:12 | |
|
просто флуд
По моему, чтоб понять суть проблемы, нужно ну уж ооочень хорошо знать анатомию подключаемых файлов. Это я, как человек прочитавший таки предупреждения компилятора, говорю
Без этого признаюсь не осилил бы (если я правильно понял суть проблемы. Надеюсь Evg нам все таки раскажет через пару дней)
0
|
|
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
||||||
| 17.02.2012, 22:22 | ||||||
|
Evg, прикольная штука
![]() размышления
0
|
||||||
|
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
|
|
| 17.02.2012, 22:29 | |
|
Vourhey, одинаково не работает(то есть работает не так, как ожидалось) на любой разрядности
спойлер
дело не в стеке, y1() есть в math.h. Мораль — переменным надо давать более осмысленные названия
0
|
|
|
387 / 151 / 16
Регистрация: 12.05.2011
Сообщений: 450
|
|
| 17.02.2012, 22:41 | |
|
неожиданно
cut
man y1
0
|
|
|
Формучанин
364 / 296 / 42
Регистрация: 02.11.2010
Сообщений: 1,245
|
||||||
| 17.02.2012, 23:03 | ||||||
|
мои мысли по поводу задачи
0
|
||||||
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|||
| 17.02.2012, 23:05 | |||
|
Мдя...
0
|
|||
|
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
|
|
| 17.02.2012, 23:08 | |
|
Vourhey
об этом я написал ещё в первом посте
0
|
|
|
|
|
| 18.02.2012, 00:01 [ТС] | |
|
Скажем так, в задаче на самом деле две подъё$ки. Первую нашли все. Но на всякий случай поясню:
Прикол N1
В линуксе в math.h есть описание функции с именем y1. Поэтому во втором блоке обращение к переменной y1 - на самом деле есть взятие адреса на эту функцию. Синус в программу был внесён только для того, чтобы оправдать появление math.h (чтобы не вызывало ненужных подозрений). В реальном коде warning'и не стреляли из-за того, что у нас стояло преобразование к int'у: "(int) y1". Т.е. преобразование к целому типу, по размерам совпадающему с указателем на функцию, тут никаких предупреждений после этого нет. Ошибку внесли в тот момент, когда в процессе наведения порядка переменную y1 из внешнего блока по невнимательности внесли во внутренний блок. После этого программа удачно скомпилилась и подставы никто не заметил
Теперь вопрос, по поводу прикола N2, который нашли далеко не все. Вопрос так же прячу, потому что он подразумевает раскрытие прикола N1, который, возможно, кому-то ещё предстоит найти Вопрос N2
В точках "point1" и "point2" в printf подаются переменные y1, но в первом случае это настоящий double, а во втором - получился указатель на функцию. Вопрос: почему в обоих случаях printf напечатал одно и то же?
1
|
|
|
Higher
|
||
| 19.02.2012, 11:41 | ||
|
_
Это вроде UB. Порылся в википедии, там говорится, что стандартом оговаривается только случай, когда передаются лишние аргументы. А тут не совпадает размер типов( ожидается double, который весит 8 байт, а получает указатель, который весит 4 байта ). Возможно, из лишних 4 байт printf читает предыдущее значение. Но это уже догадки =\
0
|
||
|
|
|||||||||||||||||||||
| 19.02.2012, 15:14 [ТС] | |||||||||||||||||||||
|
Ответ на вопрос N2
Для простоты оригинальный пример можно сократить (чтобы остались только те моменты, которые интересны для данного вопроса). Как уже подметили, причина такой ситуации заключается в том, что во второй printf подаётся формат для double (%f), в то время, как реально передаётся указатель
При вызове второго printf'а сначала в стек кладётся указатель на строку (4 байта), а затем указатель &d (тоже 4 байта). Однако при работе printf'а в тот момент, когда он разобрал форматную строку %f, он начинает из стека доставать аргумент типа double (т.е. 8 байт) и достаёт их. Но реально в этих 8 байтах в младших 4 байтах записан указатель (&d), а в старших 4 байтах лежит залипший остаток от старших 4 байт double'а, который остался от вызова первого printf'а. Я не буду глубоко вникать в формат хранения double'а, но факт в том, что в старшей половине double'а находится порядок (грубо говоря, 10 в какой степени), а в младшей - мантисса (грубо говоря, числа, после запятой). Таким образом получается, что в прочитанном double у нас сохранился порядок, но испортилась мантисса. На пальцах в десятичной форме это примерно означает, что было число 1.234567890, и последние 5 цифр из 10 затёрли и получилось 1.234500000. Т.е. получилось число, которое ненамного отличается от оригинального. Для формата %f у printf'а выводится только 5 десятичных знаков после запятой, и если попросить его напечатать больше, то разницу можно увидеть глазами. Вот пример, который моделирует то, что у нас случилось с нашим аргументом функции:
1
|
|||||||||||||||||||||
| 19.02.2012, 15:32 | |
|
Не по теме: NoMasters, а теперь внимательно прочитай сообщение выше. Вкури его. Включи мозг и подумай, при чем тут стек. Упади на колени, проси прощения и сними с себя случайно прилипший значок "Эксперт С++".
0
|
|
| 19.02.2012, 17:11 | |
Сообщение было отмечено как решение
РешениеНе по теме: Vourhey, на колени падать не стану, но значок отстрелю, раз уж такие дела.
0
|
|
| 19.02.2012, 17:27 | |
|
Не по теме: NoMasters, да я ж прикалываюсь :)
0
|
|
| 19.02.2012, 17:37 | |
|
Не по теме: Vourhey, в любом случае уж по плюсам-то я действительно не эксперт, теплый ламповой plain C с самописными велосипедами моё всё:)
0
|
|
|
|
|||||||||||||||||
| 08.04.2012, 09:42 | |||||||||||||||||
|
Ответ под катом
Evg, с такой проблеммой столкнулся и решил её где-то лет 6 назад (когда был на 2-м курсе). Её суть: в коде присутствует переменная y1,
Вот кусок math.h
Проблемма решается в один присест выносом твоих функций в namespce Evg и вызововм их в программе посредством Evg::При этом конструкция using namespace std; никак не повлияет на код.
0.147863 0.0998334 Для продолжения нажмите любую клавишу . . .
0
|
|||||||||||||||||
| 08.04.2012, 09:42 | |
|
Помогаю со студенческими работами здесь
17
Пример с учебника выдаёт ошибки Есть пример.Поиск ошибки.dev-C++ У меня случаются ошибки. Как их избегать? пример с ObjectOutputStream
Ошибки с работой MessageBox.Show, пример из книги Стиллмен, Грин Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2.
Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива.
Было так:. . .
|
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: реализовать контроль корректности заполнения дат назначения. . .
|
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html
Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
|
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
|
|
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях.
Задача: при копировании документа очищать определенные реквизиты и табличную. . .
|
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git
main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели
8ATzM_2aurI
|
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2.
Задача: запретить редактирование документа, если он открыт у другого пользователя.
/ / . . .
|
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои.
А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
|