Q: Why keywords instead of __keywords? A: We already tried __keywords; they failed.
Last week on comp.lang.c++.moderated, Nicola
Musatti wondered why C++/CLI would use keywords that don't follow the __keyword naming
convention for conforming extensions:
-
The standard already provides a way to avoid conflicts when introducing new keywords:
prepend a double underscore.
Right, and that's what Managed C++ used, for just that reason: to respect compatibility.
Unfortunately, there was a lot of resistance and it is considered a failure.
For one thing, programmers have complained loudly that all the underscores are not
only ugly, but a real pain because they're much more common throughout the code than
other extensions such as __declspec have been. In particular, __gc gets
littered throughout the programmer's code.
At least as importantly, the __keywords littered throughout the code
can make the language feel second-class, particularly when people look at equivalent
C++ and C# or VB source code side-by-side. This comparative ugliness has been a contributing,
if not essential, factor why some programmers have left C++ for other languages.
Consider:
//-------------------------------------------------------
// C# code
//
class R {
private int len;
public property int Length {
get() { return len; }
set() { len = value; }
}
};
R r = new R;
r.Length = 42;
//-------------------------------------------------------
// Managed C++ equivalent
//
__gc class R {
int len;
public:
__property int get_Length() { return len; }
__property void set_Length( int i ) { len = i; }
};
R __gc * r = new R;
r.set_Length( 42 );
Oddly, numerous programmers find the former more attractive. Particularly after the
2,000th time they type __gc.
But now we can do better:
//-------------------------------------------------------
// C++/CLI equivalent
//
ref class R {
int len;
public:
property int Length {
int get() { return len; }
void set( int i ) { len = i; }
}
};
R^ r = gcnew R;
r->Length = 42;
I should note there's actually also a shorter form for this common case, to have the
compiler automatically generate the property's getter, setter, and backing store.
While I'm at it, I'll also put the R instance on the stack which
is also a new feature of the revised syntax:
//-------------------------------------------------------
// C++/CLI alternatives
//
ref class R {
public:
property int Length;
};
R r;
r.Length = 42;
C# is adding something similar as a property shorthand. But C# doesn't have stack-based
semantics for reference types and is unlikely to ever have them, though using is
a partial automation of the stack-based lifetime control that C++ programmers take
for granted. I'll have more to say about using another time.