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: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 18.08.09 11:52
Оценка: +3
Здравствуйте, The_Thing, Вы писали:

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

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

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


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


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


ну-ну

по стандарту main может быть и такой. Более того у нее может быть опущен return, принимается return 0. Так что в этом тут порядок
---
С уважением,
Сергей Мухин
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: после Собеседования... остались вопросы
От: 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[2]: после Собеседования... остались вопросы
От: Аноним  
Дата: 19.08.09 07:30
Оценка: -1
СМ>вообще то использование this == 0 есть UB

Я, например, люблю использовать такой спецэффект:

class MyClass
{
    int        a;
    static MyClass Array[100];
public:
    int Index() {return this?this-Array:0;}
    static MyClass* Get(int Index) {return &Array[Index];}
};

MyClass MyClass::Array[100];

int main()
{
    MyClass*            a1 = 0;
    MyClass*            a2 = MyClass::Get(1);
        int Integer;

    Integer = a1->Index(); // Равно 0
    Integer = a2->Index(); // Равно 1
        
        return 0;
}


И все работает, даже если this=0. Никаких предупреждений (компилятор Visual Studio 2005).
Re[3]: после Собеседования... остались вопросы
От: Кодт Россия  
Дата: 19.08.09 08:28
Оценка: +1
Здравствуйте, <Аноним>, Вы писали:

А>Я, например, люблю использовать такой спецэффект:


Пожалуйста: дистиллированный фейерверк для твоего спецэффекта
struct Base
{
    void unsafe()
    {
        printf("unsafe %p\n", this);
    }
    static void bypass()
    {
        printf("bypass\n");
    }
    void safe()
    {
        if(this)
            unsafe();
        else
            bypass();
    }
};

struct Shift
{
    int x;
};

struct Derived : Shift, Base
{
};

int main()
{
    Base* pb = 0;
    pb->safe(); // bypass()
    Derived* pd = 0;
    pb = pd;    // static_cast корректно приводит 0 к 0
    pb->safe(); // далее - bypass()
    pd->safe(); // а вот здесь наблюдаем опаньки!
}

Забавно, что gcc бережно относится к нулевым ссылкам, тогда как VC считает, что нулевая ссылка — это фантастика, и без лишних проверок сдвигает базу.
Хотя, может быть, поведение gcc зависит от опций...
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
после Собеседования... остались вопросы
От: 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[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[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: после Собеседования... остались вопросы
От: Аноним  
Дата: 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[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 — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Re: NULL->method()
От: Roman Odaisky Украина  
Дата: 18.08.09 20:09
Оценка:
Нельзя вызывать методы по нулевому указателю! Даже те, которые не обращаются к this! Это Undefined behaviour, и точка.

Если интересно, как именно это может навернуться, см. http://rsdn.ru/forum/cpp/50149.aspx
Автор: Андрей Тарасевич
Дата: 28.04.02
.
До последнего не верил в пирамиду Лебедева.
Re[2]: после Собеседования... остались вопросы
От: Bell Россия  
Дата: 19.08.09 03:30
Оценка:
Здравствуйте, catBasilio, Вы писали:

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

Хоть с virtual, хоть без virtual — это неопределенное поведение. Тема обсуждалась уже не один раз.
Например, рекомендую вот этот топик: http://rsdn.ru/forum/cpp/49650.aspx
Автор: DarkGray
Дата: 26.04.02
Любите книгу — источник знаний (с) М.Горький
Re[7]: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 19.08.09 04:37
Оценка:
Здравствуйте, catBasilio, Вы писали:


B>там return 0 еще писать надо (я если честно не знал, что ретурн в майне можно не писать).


Это совершенно не нужные знания. Можно сразу и забыть
---
С уважением,
Сергей Мухин
Re[3]: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 19.08.09 07:39
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>Я, например, люблю использовать такой спецэффект:


заведомо использовать UB не есть хорошо.
---
С уважением,
Сергей Мухин
Re[4]: после Собеседования... остались вопросы
От: Сергей Мухин Россия  
Дата: 19.08.09 08:34
Оценка:
Здравствуйте, Кодт, Вы писали:


А>>Я, например, люблю использовать такой спецэффект:



К>Забавно, что gcc бережно относится к нулевым ссылкам, тогда как VC считает, что нулевая ссылка — это фантастика, и без лишних проверок сдвигает базу.


я не уверен, но разве 0 не должен приводится к 0 по стандарту?
---
С уважением,
Сергей Мухин
Re: после Собеседования... остались вопросы
От: MasterZiv СССР  
Дата: 19.08.09 21:52
Оценка:
The_Thing пишет:


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

Ну и чего, не прошёл ?

Это был гон, правильный ответ (который ты должен был выдать) --
разименование нулевого указателя -- UB. Далее предсказать поведение
программы не представляется возможным.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.