> ref class Derived : public Base {
> protected:
> virtual void SomeVirtualFunction()
> {Console::WriteLine(L"Derived");}
> };
Sorry I copied the wrong code:
ref class Derived : public Base {
protected:
virtual void SomeVirtualFunction() override
{Console::WriteLine(L"Derived");}
};
Note the override keyword, it indicates that the function is not
replacing Base::SomeVirtualFunction, but is overriding it.
Tom
Hi Tom.
>Unfortunately in .NET virtual functions can't be private, they must be protected
But I am pretty sure CLR allows private virtual functions. It works
fine with old MC++.
>But even that modification won't solve your problem, you even have to declare the function override to override a virtual function.
Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
like this "controlled virtuality". Just have no idea why to disable
private virtual functions. Any clues?
Tamas Demjen - 23 Jun 2005 00:01 GMT
> Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
> like this "controlled virtuality". Just have no idea why to disable
> private virtual functions. Any clues?
The reason I don't like this override keyword is that because if you
miss it, the function won't work like a virtual function anymore, and
there's not even a compiler warning. No override keyword == non-virtual
function, even if the virtual keyword is there. It's very frustrating
when you have a virtual function and it's not polymorphic.
If I make the virtual function private, I get the following .NET runtime
exception:
<quote>
An unhandled exception of type 'System.TypeLoadException' occurred in
Virtual.exe
Additional information: Method 'SomeVirtualFunction' on type 'Derived'
from assembly 'Virtual, Version=1.0.1999.26811, Culture=neutral,
PublicKeyToken=null' is overriding a method that is not visible from
that assembly.
</quote>
This is not a language feature, it's a .NET runtime exception, which
clearly states that overriding a private virtual function is not
supported by the runtime library.
I don't know if it's intentional, but this is happening with VC++ 2005
Beta2.
Tom
Nemanja Trifunovic - 23 Jun 2005 03:16 GMT
You are right - it does throw. However, with VC++ 2003, the following
code works just fine:
__gc class Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(S"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};
__gc class Derived : public Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};
int _tmain()
{
Base* handle = new Derived();
handle->SomeAccessibleFunction();
return 0;
}
Did they introduce this "feature" in CLR 2.0? That would be very
strange, indeed.
Nemanja Trifunovic - 23 Jun 2005 20:02 GMT
And the same code on VC++2005 with /clr:oldsyntax gives the following
warning:
.\PrivateVirtual.cpp(46) : warning C4445: 'void
Base::SomeVirtualFunction(void)' : in a managed type a virtual method
cannot be private
.\PrivateVirtual.cpp(54) : warning C4445: 'void
Derived::SomeVirtualFunction(void)' : in a managed type a virtual
method cannot be private
But it works just fine!!!
Hehehe, is it weird or what? I'm gonna start ILDasm now to see what's
going on...
Nemanja Trifunovic - 23 Jun 2005 20:57 GMT
Hmmm.. here's the difference:
"/clr:oldsyntax":
.method private virtual instance void SomeVirtualFunction() cil
managed
{
...
"/clr":
.method private hidebysig strict virtual
instance void SomeVirtualFunction() cil managed
{
So the difference is "hidebysig strict" part. AFAIK hidebysig is
ignored by runetime and is used only by tools, but what the heck is
"strict"? I don't remember seing it before...
Ronald Laeremans [MSFT] - 24 Jun 2005 00:00 GMT
> Hmmm.. here's the difference:
>
[quoted text clipped - 14 lines]
> ignored by runetime and is used only by tools, but what the heck is
> "strict"? I don't remember seing it before...
It means exactly what this thread is about: It prevents a private member
function from being overriden in a derived class. The reason the CLR
added this (and all the Microsoft languages emit this) is that the
design of the BCL and FX and common design pattersn in .NET make this a
security issue. Many base classes base security and threat model
analysis on the fact that a derived class cannot be inserted and change
behavior in the base class (like validation) that needs to bge immune to
being changed by further derived classes.
Ronald Laeremans
Visual C++
Nemanja Trifunovic - 24 Jun 2005 02:20 GMT
Thanks Ronald, it makes sense.
Was "strict" added in CLR 2.0? I don't remember it from v1.1.
Brandon Bray [MSFT] - 24 Jun 2005 01:55 GMT
> The reason I don't like this override keyword is that because if you
> miss it, the function won't work like a virtual function anymore, and
> there's not even a compiler warning. No override keyword == non-virtual
> function, even if the virtual keyword is there. It's very frustrating
> when you have a virtual function and it's not polymorphic.
I'm not sure why you're not seeing a warning because there are plenty of
them for this scenario. In any case, the compiler team decided to change the
warnings into errors after Beta 2. When Visual C++ 2005 ships, you'll be
required to put the "new" or "override" keyword there. The code will not
compile otherwise.

Signature
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Tamas Demjen - 24 Jun 2005 17:21 GMT
> I'm not sure why you're not seeing a warning because there are plenty of
> them for this scenario. In any case, the compiler team decided to change the
> warnings into errors after Beta 2. When Visual C++ 2005 ships, you'll be
> required to put the "new" or "override" keyword there. The code will not
> compile otherwise.
There is indeed a warning that I overlooked. Excellent, thanks, Brandon.
Sorry for the confusion.
Tom
Alexei - 23 Jun 2005 06:51 GMT
> Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
> like this "controlled virtuality". Just have no idea why to disable
> private virtual functions. Any clues?
Let me take a wild guess. Interoperability with other .NET languages?
Brandon Bray [MSFT] - 24 Jun 2005 01:49 GMT
>> Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
>> like this "controlled virtuality". Just have no idea why to disable
>> private virtual functions. Any clues?
>
> Let me take a wild guess. Interoperability with other .NET languages?
We wanted C++ to be as secure as other languages. :-) It was determined that
giving up the ability to override inaccessible virtual functions was a good
tradeoff with the coding practices that would have to be employed to avoid
the security problems (see my other post).

Signature
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Brandon Bray [MSFT] - 24 Jun 2005 01:46 GMT
> Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
> like this "controlled virtuality". Just have no idea why to disable
> private virtual functions. Any clues?
Private virtual functions are still useful for one scenario. In ref classes,
in order to override a virtual function, you have to have access to call it.
Since a private virtual function can never be called from outside the class,
it can never be overridden. Thus, to make the compiler stop issuing a
diagnostic for the private virtual function, you can use the "sealed"
keyword.
Now, virtual functions are also used to implement interface contracts. So,
if you want to implement an interface without changing the API exposed
directly from the type, you can implement the funtion with a private sealed
virtual function.
The last thing to bring up is why overriding a virtual function to which you
do not have access is a security issue in ref classes but not native
classes. For ref classes, types can be derived accross assembly boundaries.
Inheriting native classes have never been supported across DLL boundaries
with any fidelity. Many times a ref class would make its virtual functions
"internal" because they were only needed inside the assembly. In version 1.0
of the CLR, any type could override a virtual function. That was intentional
because the CLR wanted to support the C++ semantics. The security issue was
found after 1.0 shipped, and the strict semantics were introduced in version
1.1. C# used the strict semantics in 1.1, and we chose to follow suit with
the new C++ syntax in Visual C++ 2005.
Hope that helps!

Signature
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Nemanja Trifunovic - 24 Jun 2005 02:18 GMT
> Hope that helps!
Absolutelly. Thanks a lot for your detailed explanation. I wasn't aware
of the security issue you mention.
Nishant Sivakumar - 24 Jun 2005 11:44 GMT
Interesting thread - thanks Nemanja :-)

Signature
Regards,
Nish [VC++ MVP]
http://www.voidnish.com
http://blog.voidnish.com
>> Hope that helps!
>
> Absolutelly. Thanks a lot for your detailed explanation. I wasn't aware
> of the security issue you mention.