Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: вызов нестатической функции несозданного объекта  (Прочитано 7422 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Migmile
Помогающий

ru
Offline Offline

« : 29-09-2006 09:17 » 

Приятель прислал вопрос, а у меня нет времени копаться в документации, может кто сразу скажет, как стандарт относится к:
struct A
{
int x;
int f() {return 1;}
};

A * p = 0;
int y = p->f(); // should work, huh ?
p->x = 0; // AV !

В моем понимании предпоследняя строчка не должна допускаться стандартом!
Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 29-09-2006 09:45 » 

Это то же самое, что писать по нулевому указателю:
Код:
int *p = 0;
*p = 25;
Код собирается без проблем, но вовремя выполнения выскакивает ошибка, попытки записать по адресу 0x00000000.
Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 29-09-2006 09:49 » 

Стандарт не подрузамевает проверку коректности указателей. Программист сам отвечает за все указатели в программе.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #3 : 29-09-2006 11:21 » 

Migmile, всё праввильно так и должно быть, если зыбыть про нулевой указатель.
Записан

Странно всё это....
Migmile
Помогающий

ru
Offline Offline

« Ответ #4 : 29-09-2006 12:19 » 

Мне казалось, что вызывать функциии несуществующего объекта можно, толко если они (функции) - статические!
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 29-09-2006 12:36 » 

Вообще-то Migmile спросил про стандарт, в котором ковырятся наверняка у всех нет времени. Так сказать "по букве закона". Я бы объяснил это след. образом.

К статическим функциям объекта это никак не относится, их можно рассматривать как глобальные.
Я думаю, тут всё немного сложнее.

В данном случае мы имеем инлайн ф-ю, которая практически ничего не делает. Те просто возвращает константу. По определению объекта функция мембер работает с полями данных этого объекта. Попробуй вернуть например значение х в ф-ции f(). И увидишь, что это не прокатывает тк данные не существуют. А в данном примере ф-я не делает ничего с объектом. Те она "объектнонезависима".
С другой стороны мы имеем дело с ещё однм явлением - разыменованием нулевого указателя. При совокупности этих факторов - ничего удивительного, что это работает. Таблица ф-ций содержит инфу о f(), нулевой указатель типа А говорит, где её можно найти ну а дальше как говорится дело техники. Я не удивлюсь если компилятор на этом месте просто не поставит 1. Хотя это тоже зависит от компилятора.

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

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #6 : 29-09-2006 12:40 » 

Migmile, через указатель можешь вызывать всё, что угодно, при условии валидности указателя иначе runtime error
статичные функции для не существующего
объекта вызываются обычно так
A::foo();
Записан

Странно всё это....
Migmile
Помогающий

ru
Offline Offline

« Ответ #7 : 29-09-2006 15:57 » 

Ну, господа, мое-то мнение таково: если говорить о безопасности, то такого допускать нельзя! И это должно быть оговорено в стандарте! (IMHO)
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 29-09-2006 17:08 » 

Migmile, На стадии компиляции это очень сложно отследить. Поэтому разработчики компиляторов практически не заморачиваются на таких вешах. Хотя на очевидные веши могут кинуть ворнинг.
Когда вызывается функция класса, в регистре CX передается указатель на экземпляр класса. Если бы функция была бы виртуальной, то выскочила бы  автоматически ошибка. Так как ссылка на массив указателей виртуальных функций хранится также вместе с экземпляром класса. 
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 29-09-2006 18:16 » 

И это должно быть оговорено в стандарте! (IMHO)

Причём тут безопасность - не совсем понятно. Стабильность - да. Ну да ладно. Наверное зависит от области применения. А вот про стандарт - что именно должно там быть написано? Что объекты надо создавать?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 30-09-2006 16:44 » 

Цитата
А вот про стандарт - что именно должно там быть написано? Что объекты надо создавать?
В данном случае, скорее, что указатель должен указывать на экземпляр структуры. Вообще, укказателем можно пользоваться только если он на что-то указывает. Наверное, это в стандарте как-то отражено.
« Последнее редактирование: 30-09-2006 16:47 от nikedeforest » Записан

ещё один вопрос ...
LP
Помогающий

ru
Offline Offline

« Ответ #11 : 03-10-2006 12:47 » 

Вот, что говорит стандарт:
Цитата
5.2.5 p.3
If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form    (*(E1)).E2;
То есть p->f() эквивалентно (*p).f(). Имеем разыменование нулевого указателя, что приводит к неопределенному поведению
Цитата
1.9 p.4
Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer).

На практике при вызове функции-члена через указатель, адрес хранящийся в указателе помещается в регистр (ECX для MSVC) или в стек (GCC, Borland). В данном случае туда помещается NULL, так как обращений к данным членам в функции f() нет, то это и не приводит к проблемам, потому что реально обращение к указателю не происходит.
« Последнее редактирование: 03-10-2006 12:50 от LP » Записан

Если эта надпись уменьшается, значит ваш монитор уносят
Migmile
Помогающий

ru
Offline Offline

« Ответ #12 : 03-10-2006 15:04 » 

LP, спасибо за стандарт:)
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines