%\pagebreak
\section{C++ Virtual Functions}
\label{sec:virtual_functions}

\index{mapping!virtual functions, C++}

The 5.2 OpenMP Specification clarified restrictions on the use 
of polymorphic classes and virtual functions when used within 
\kcode{target} regions. The following examples illustrate 
use cases and the limitations imposed by restrictions for
references and the use of Unified Shared Memory. 

The first example illustrates two simple cases of using a virtual function
through a pointer and reference without Unified Shared Memory. 

A class, \ucode{D}, is derived from class \ucode{A}.  
Function \ucode{vf} in class \ucode{A} is declared
virtual, and the function \ucode{vf} in class \ucode{D} is declared with override.
An object, \ucode{d} of type \ucode{D}, is created and mapped through a \kcode{target data}
directive.

In the first case, a pointer of type \ucode{A}, \ucode{ap}, is assigned to point 
to the derived object \ucode{d}, and in the first \kcode{target} region the pointer
is used to call the \ucode{vf} function of the derived class, \ucode{D}.

In the second case, the reference variable \ucode{ar} of type \ucode{A} references 
the derived object \ucode{d}).  The use of the reference variable \ucode{ar} 
in the \kcode{target} region is illegal due to the restriction that the static and dynamic 
types must match when mapping an object for the first time.
That is, the behavior of the implicit map of \ucode{ar} 
is non-conforming -- its static type \ucode{A} doesn't match its dynamic type \ucode{D}.  
Hence the behavior of the access to the virtual functions is unspecified.

\cppexample[5.2]{virtual_functions}{1}

The second example illustrates the restriction:

\emph{``Invoking a virtual member function of an object on a device other than the device on which the
object was constructed results in unspecified behavior, unless the object is accessible and was
constructed on the host device.''}

In the first case, an instantiation \ucode{ap} of a polymorphic class (\ucode{A}) occurs in the 
\kcode{target} region, and access of its virtual function
is incorrectly attempted on the host (another device).

In the second case, the object \ucode{ap} is instantiated on the host; access of \ucode{ap} within
the next \kcode{target} region is permitted. (Unified Shared Memory is
used here to minimize mapping concerns.)

\cppexample[5.2]{virtual_functions}{2}
