после Собеседования... остались вопросы
От: The_Thing Россия
Дата: 18.08.09 11:30
Оценка:
Только что с собеседования.
И попался такой вопрос (см ниже):


#include "iostream"

class A { public: virtual void f() =0; };
class B { public: virtual void f() { std::cout<< "My string"<<std::endl; } };

void main()
{
// обращаю внимание, что троиточия между кодом нет, весь код "как есть".

    A *a = 0; // здесь именно нули
    B *b = 0; // здесь именно нули

    //a->f();
    b->f();
}


Если я не ошибаюсь, то была именно такая запись. Был вопрос, как поведёт себя программа. Правильный ответ был озвучен так: если снять комментарий с "a->f();", то программа ругнется Unhandle (так и было мною сказано), а вот b->f(); должен выдать строку "My string"
И сослались на устройство виртуальной таблицы и стандарт (после поста сразу лезу в стандарт, что бы узнать).

Попробовал на MSVC 2008, b->f() также выдало Unhadled.
Это был гон, или ошибка компилятора Действительно ли это так?

p.s. Если тут окажется человек с которым я сегодня беседовал прошу подключиться к топику.
Re: после Собеседования... остались вопросы
От: Ovl Россия  
Дата: 18.08.09 11:51
Оценка:
это действительно так. никакого "My string" там конечно же не вывелось бы.
надо где-то иметь ссылку на ТВФ, поэтому валидный указатель на объект крайне желателен.
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 18.08.09 11:52
Оценка: +3
Здравствуйте, The_Thing, Вы писали:

вообще то использование this == 0 есть UB

но конкретный компилятор, с конкретными опциями (макс оптимизация, например) может выполнить вторую строчку.

Но это ничего не значит.
---
С уважением,
Сергей Мухин
Re[2]: после Собеседования... остались вопросы
От: Аноним  
Дата: 18.08.09 12:21
Оценка:
Здравствуйте, Ovl, Вы писали:

Ovl>это действительно так. никакого "My string" там конечно же не вывелось бы.

Ovl>надо где-то иметь ссылку на ТВФ, поэтому валидный указатель на объект крайне желателен.

Т.е. запись корректна?
Re[3]: после Собеседования... остались вопросы
От: Ovl Россия  
Дата: 18.08.09 12:27
Оценка:
А>Т.е. запись корректна?
в смысле — запись?
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re: после Собеседования... остались вопросы
От: catBasilio  
Дата: 18.08.09 12:32
Оценка: 2 (2) -2
Здравствуйте, The_Thing, Вы писали:


T_T>Попробовал на MSVC 2008, b->f() также выдало Unhadled.

T_T>Это был гон, или ошибка компилятора Действительно ли это так?

T_T>p.s. Если тут окажется человек с которым я сегодня беседовал прошу подключиться к топику.


Будет работать без virtual


  class A {public: void f() { std::cout << "hello world!" << std::endl;};

  void main(void)
  {
    A* a = 0;
    a->f();
  }


в таком случае должно выдаться hello world потому что нет никаких таблиц виртуальных функций. а сама функция f() имеет фиксированный адрес в памяти.

Вообще для компилятора не виртуальная функция это просто функция, которой неявно передается this. функция примерно равна

void f(A* this)
{
  std::cout << "hello world!" << std::endl;
}


и не важно что this == 0. так как в теле нет обращения к мемберам класса, то все будет работать.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Re[2]: после Собеседования... остались вопросы
От: The_Thing Россия
Дата: 18.08.09 12:40
Оценка:
Здравствуйте, catBasilio, Вы писали:

B>Здравствуйте, The_Thing, Вы писали:



T_T>>Попробовал на MSVC 2008, b->f() также выдало Unhadled.

T_T>>Это был гон, или ошибка компилятора Действительно ли это так?

T_T>>p.s. Если тут окажется человек с которым я сегодня беседовал прошу подключиться к топику.


B>Будет работать без virtual



B>
B>  class A {public: void f() { std::cout << "hello world!" << std::endl;};

B>  void main(void)
B>  {
B>    A* a = 0;
    a->>f();
B>  }
B>


B>в таком случае должно выдаться hello world потому что нет никаких таблиц виртуальных функций. а сама функция f() имеет фиксированный адрес в памяти.


B>Вообще для компилятора не виртуальная функция это просто функция, которой неявно передается this. функция примерно равна


B>
B>void f(A* this)
B>{
B>  std::cout << "hello world!" << std::endl;
B>}
B>


B>и не важно что this == 0. так как в теле нет обращения к мемберам класса, то все будет работать.


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

Ушёл зубрить стандарт!
Re: после Собеседования... остались вопросы
От: Alexander G Украина  
Дата: 18.08.09 12:53
Оценка: +1
Здравствуйте, The_Thing, Вы писали:

T_T>Если я не ошибаюсь, то была именно такая запись. Был вопрос, как поведёт себя программа. Правильный ответ был озвучен так: если снять комментарий с "a->f();", то программа ругнется Unhandle (так и было мною сказано), а вот b->f(); должен выдать строку "My string"

T_T>И сослались на устройство виртуальной таблицы и стандарт (после поста сразу лезу в стандарт, что бы узнать).

дурной вопрос. можно разве что какой-либо ход мысли учитывать как правильный/неправильный, но не такой ответ.
Русский военный корабль идёт ко дну!
Re[2]: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 18.08.09 13:00
Оценка: +1
Здравствуйте, Alexander G, Вы писали:

T_T>>Если я не ошибаюсь, то была именно такая запись. Был вопрос, как поведёт себя программа. Правильный ответ был озвучен так: если снять комментарий с "a->f();", то программа ругнется Unhandle (так и было мною сказано), а вот b->f(); должен выдать строку "My string"

T_T>>И сослались на устройство виртуальной таблицы и стандарт (после поста сразу лезу в стандарт, что бы узнать).

AG>дурной вопрос. можно разве что какой-либо ход мысли учитывать как правильный/неправильный, но не такой ответ.


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

по стандарту ИМХО это как минимум UB.

по жизни зависит от компилятора и даже от опций.

в реальной жизни надо конечно понимать что происходит в обычном случае. Это наверно и надо было рассказать. Отличие вирт от не вирт, this и тп.
---
С уважением,
Сергей Мухин
Re: после Собеседования... остались вопросы
От: Аноним  
Дата: 18.08.09 13:49
Оценка:
Здравствуйте, The_Thing, Вы писали:

Нет, тут только моё незнание. Вопрос был на понимание.
Re[2]: после Собеседования... остались вопросы
От: Николай Ивченков  
Дата: 18.08.09 15:05
Оценка:
catBasilio:

B>
  class A {public: void f() { std::cout << "hello world!" << std::endl;};

  void main(void)
  {
    A* a = 0;
    a->f();
  }


B>в таком случае должно выдаться hello world потому что нет никаких таблиц виртуальных функций. а сама функция f() имеет фиксированный адрес в памяти.


По стандарту main должна возвращать int.
Если тип возврата main привести в норму, здесь будет undefined behavior, как и в случае с виртуальными функциями.

5.2.5/3:

If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot)

Разыменование выражения, вычисляющегося в null pointer value, допускается только в случае, когда это выражение является операндом typeid, а в остальных случаях это приводит к undefined behavior.
Re: после Собеседования... остались вопросы
От: jazzer Россия Skype: enerjazzer
Дата: 18.08.09 15:32
Оценка: :))
Здравствуйте, The_Thing, Вы писали:

T_T>Был вопрос, как поведёт себя программа.


известно как — отформатирует винчестер.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: после Собеседования... остались вопросы
От: jazzer Россия Skype: enerjazzer
Дата: 18.08.09 15:33
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Ovl, Вы писали:


Ovl>>это действительно так. никакого "My string" там конечно же не вывелось бы.

Ovl>>надо где-то иметь ссылку на ТВФ, поэтому валидный указатель на объект крайне желателен.

А>Т.е. запись корректна?


Нет, запись противоречит стандарту (разыменование нулевого указателя), так что компилятор может делать все, что ему заблагорассудится (обычное действие в таких случаях, реализованное во всех нормальных компиляторах — форматирование винчестера).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 18.08.09 16:07
Оценка: -3
Здравствуйте, Николай Ивченков, Вы писали:


B>>в таком случае должно выдаться hello world потому что нет никаких таблиц виртуальных функций. а сама функция f() имеет фиксированный адрес в памяти.


НИ>По стандарту main должна возвращать int.


ну-ну

по стандарту main может быть и такой. Более того у нее может быть опущен return, принимается return 0. Так что в этом тут порядок
---
С уважением,
Сергей Мухин
Re[4]: после Собеседования... остались вопросы
От: Николай Ивченков  
Дата: 18.08.09 16:29
Оценка:
Сергей Мухин:

СМ>по стандарту main может быть и такой.


3.6.1/2:

An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.

(под "its type" имеется в виду тип функции, а не "return type")

Данное правило относится к diagnosable semantic rules, и его нарушение должно сопровождаться выдачей диагностического сообщения. Реализация имеет право успешно компилировать и выполнять неправильно сформированную программу лишь на основаниях 1.4/8 (при этом выдача диагностического сообщения всё равно требуется).
Re[4]: после Собеседования... остались вопросы
От: Bender Bending Rodriguez Россия  
Дата: 18.08.09 16:29
Оценка:
Здравствуйте, Сергей Мухин, Вы писали:

СМ>по стандарту main может быть и такой. Более того у нее может быть опущен return, принимается return 0. Так что в этом тут порядок



An implementation shall not predefine the main function. This function shall not be overloaded. It shall
have a return type of type int, but otherwise its type is implementation-defined. All implementations
shall allow both of the following definitions of main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }

In the latter form argc shall be the number of arguments passed to the program from the environment in
which the program is run. If argc is nonzero these arguments shall be supplied in argv[0] through
argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (NTMBSs)
(17.3.2.1.3.2) and argv[0] shall be the pointer to the initial character of a NTMBS that represents the
name used to invoke the program or "". The value of argc shall be nonnegative. The value of
argv[argc] shall be 0. [Note: it is recommended that any further (optional) parameters be added after
argv. ]


так что только int.
Re[5]: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 18.08.09 17:09
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Сергей Мухин:


СМ>>по стандарту main может быть и такой.


НИ>3.6.1/2:

НИ>

An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.

НИ>(под "its type" имеется в виду тип функции, а не "return type")

НИ>Данное правило относится к diagnosable semantic rules, и его нарушение должно сопровождаться выдачей диагностического сообщения. Реализация имеет право успешно компилировать и выполнять неправильно сформированную программу лишь на основаниях 1.4/8 (при этом выдача диагностического сообщения всё равно требуется).


согласен, но return то можно не писать
---
С уважением,
Сергей Мухин
Re[4]: после Собеседования... остались вопросы
От: catBasilio  
Дата: 18.08.09 18:28
Оценка:
Здравствуйте, Сергей Мухин, Вы писали:

СМ>Здравствуйте, Николай Ивченков, Вы писали:



B>>>в таком случае должно выдаться hello world потому что нет никаких таблиц виртуальных функций. а сама функция f() имеет фиксированный адрес в памяти.


НИ>>По стандарту main должна возвращать int.


СМ>ну-ну


СМ>по стандарту main может быть и такой. Более того у нее может быть опущен return, принимается return 0. Так что в этом тут порядок


Ну что вы придрались к функции main. я ее написал так, чтобы было меньше букв. Не в main ведь вопрос.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Re[5]: после Собеседования... остались вопросы
От: jazzer Россия Skype: enerjazzer
Дата: 18.08.09 18:43
Оценка:
Здравствуйте, catBasilio, Вы писали:

B>Ну что вы придрались к функции main. я ее написал так, чтобы было меньше букв. Не в main ведь вопрос.


Э-э-э... Вообще-то в int меньше букв, чем в void

void main(void); // твой вариант, совсем плохой, зато короткий
int main(); // правильный вариант
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: после Собеседования... остались вопросы
От: catBasilio  
Дата: 18.08.09 18:51
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, catBasilio, Вы писали:


B>>Ну что вы придрались к функции main. я ее написал так, чтобы было меньше букв. Не в main ведь вопрос.


J>Э-э-э... Вообще-то в int меньше букв, чем в void


там return 0 еще писать надо (я если честно не знал, что ретурн в майне можно не писать).
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.