virtual-by-default rant

Adam D. Ruppe destructionator at gmail.com
Sat Mar 24 08:16:32 PDT 2012


On Saturday, 24 March 2012 at 10:56:27 UTC, Manu wrote:
> My objection to virtual-by-default, but, acknowledging that 
> can't be changed, insistence on a virtual keyword
> is this.

I like the idea of a virtual keyword btw.

> Adding a system like you describe to validate virtuals is not a 
> complexity I'm interested in implementing


You already have! Let me quote one of your previous posts:

"I sincerely fear finding myself false-virtual hunting on build 
night until
2am trying to get the game to hold its frame rate (I already do 
this in
C++, but at least you can grep for and validate them!)."


In C++, you're hunting for false virtuals right now.

Your solution is to grep for and validate them.


That's what I'm talking about here, but instead of grepping,
using the language's reflection capabilities for an automated
test.

Check out the example I pasted at the end of this message.

The bottom part of that is reusable, the top part is my
test data.

Run it through the compiler with the test code added:

$ dmd test13 -unittest
Warning: A.lol is an unauthorized virtual function
Warning: B.amazing is an unauthorized virtual function


And it greps for virtuals for you, and reports
it at compile time.

If it turns out you want one of them to be virtual,
you add the name to the authorizedVirtuals list.

How would you validate a virtual in C++? If
you have a list of functions you're OK with,
that's exactly what this is!

If you look at the source of each virtual your
grep finds, to ensure it absolutely needs to
be virtual... well, you can do that here too. Between
the warnings and the authorized virtuals list, you know
all the virts here and can review them.


The best way to silence a warning btw is to just
write "final" on the method.

Your code review process can keep the authorized
virtual list to themselves, so most developers
either add final or break the build. Either way,
no virtuals slip in without review.


Also from an old post:

"Aside from that, I want a compile error if someone tries to 
randomly
override stuff."

Warning: C.goodVirtual is an unauthorized virtual function

the code below checks on a per class level, so if you don't
authorize the override, it gets a warning to.

(You can change these to errors by making it static assert
or something instead of pragma(msg).)


> Who maintains these tables?

Who decides who can write "virtual" in C++?




Example follows:


===
module test13;

class A {
	void goodVirtual() {}
	void lol() {}
}

class B {
	int amazing() { return 0; }
}

class C : A {
	override void goodVirtual() {}
	final void drox() {}
}

template isClass(alias T) if(!is(T)) { enum bool isClass = false; 
}
template isClass(alias T) if(is(T)) { enum bool isClass = is(T == 
class); }

unittest {
	enum string[][string] authorizedVirtuals = [
		"A" : ["goodVirtual"],
		"B" : [],
		"C" : ["goodVirtual"],
	];

	import algore = std.algorithm;

	foreach(member; __traits(allMembers, test13)) {
		static if(isClass!(__traits(getMember, test13, member))) {
			foreach(possibleVirt; __traits(derivedMembers, 
__traits(getMember, test13, member))) {
				static if(
					__traits(isVirtualMethod, __traits(getMember,
						__traits(getMember, test13, member), possibleVirt))
					&&
					!algore.canFind(authorizedVirtuals[member], possibleVirt))
				{
					pragma(msg, "Warning: " ~ member ~ "." ~ possibleVirt ~ " is 
an unauthorized virtual function");
				}
			}
		}
	}
}

void main() {}

===




More information about the Digitalmars-d mailing list