Здравствуйте, rus blood, Вы писали:
RB>If you attempt to instantiate a class marked with novtable and then access a class member, you will receive an access violation (AV).
Не AV, а
любое другое UB.
#include <stdio.h>
struct __declspec(novtable) A
{
A() { printf("%p A::ctor\n", this); }
~A() { printf("%p A::dtor\n", this); }
virtual void foo() { printf("%p A::foo\n", this); }
void bar() { A::foo(); }
void buz() { foo(); }
};
struct B
{
virtual void hello() { printf("%p B::hello\n", this); }
};
typedef int (*FUN)();
FUN pvfc_table[1] = { _purecall };
int surprize() { printf("surprize!\n"); return 0; }
FUN surprize_table[1] = { surprize };
template<FUN* table>
struct С
{
С() : p(table) {}
FUN* p;
};
void runA()
{
A a;
a.foo();
a.bar();
a.buz();
}
template<class T>
void runT()
{
T t;
}
int main()
{
__try
{
// выберите любой вариант
runT< B >();
runT< C<nullptr> >();
runT< C<pvfc_table> >();
runT< C<surprize_table> >();
runT< C<(FUN*)0xDEADFACE> >();
runA();
}
__except(1)
{
printf("catastropha!\n");
}
}
Фокус в том, что наш объект A вообще не инициализирует vptr — и хватает любой мусор, лежавший там до конструирования.