Sdílet prostřednictvím


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.

Comments

  • Anonymous
    November 17, 2003
    The comment has been removed
  • Anonymous
    November 17, 2003
    I still don't like the use of plain keywords and new operators in a C++ extension; I believe that these should be reserved for the evolution of the language itself.I share the point of view that the original Managed Extensions lead to very ugly code, but the example you posted looks like what I call C+++. Is it reasonable/useful to have a new, transitional language between C++ and C#?A better alternative would be the combination of different forms of syntax: some standard compliant declarations, a few extended keywords, one or to additions to the C++ standard. Here are a few examples:Properties are a topic of general interest; a better effort should be made to have them included in the next version of the standard? What happened to the Borland proposal?The hat symbol and gcnew could be replaced with a template like syntax, e.g.cli::handle<R> r = cli::gcnew<R>();R->Length = 42;When you're done:cli::gcdelete(r);__gc classes could be declared by making their constructors private and making gcnew their friend, or by deriving them from a conventional ancestor; Otherwise the __gc keyword could be retained.System:: classes' semantics would be defined by the fact that they belong to a conventional namespace and would behave sort of like a typedef'ed smart pointer: you could declare their instances without a pointer like syntax (eg.:System::String s;but access their members with the arrow operator.I'm aware that these are very rough ideas and that there are very many aspects I didn't consider. I don't have the knowledge nor the time to turn these into a serious proposal. Yet I believe that the general ideas behind them are better respectful of the spirit of the C++ standard than the glimpses I cought of the current proposal and they might even be better acceptable to standard C++ programmers.
  • Anonymous
    November 18, 2003
    So when do we get to use the new Managed extensions? Whidby?
  • Anonymous
    November 18, 2003
    The whole concept of context-sensitive keywords gives me caution. It seems like a big if that this won't cause compatibility problems due to namespace clashes -- I mean, isn't this a Big Change to the way C++ is parsed?Was any consideration given to extending the namespace concept a little bit to allow keywords to be placed in a namespace?For example:clr::ref class R{};orusing namespace clr;ref class R{};Seems like this would solve the verbosity problem and the clashing problem. I haven't implemented a C++ parser, so it's very well that this approach wouldn't work in practice, but I'd like to know why.
  • Anonymous
    November 21, 2003
    R^ r = gcnew R; Oh man, I just had a flashback to my baby programmer classes where I used Pascal. shiver ;-)
  • Anonymous
    November 21, 2003
    Re when: Yes, the C++/CLI work is part of Whidbey.Re keywords: I'll write another blog entry about that soon. >Properties are a topic of general interest; a better effort should be>made to have them included in the next version of the standard? What>happened to the Borland proposal?Meta-comment: In standards, nothing happens except when someone decides to invest the expertise, time, and energy to write and champion a proposal. I think the ISO C++ committee would probably be favorable to looking at properties -- and threads, for that matter. But that can only happen if someone steps up to do the work, and no one currently involved in the committee has so far demonstrated the bandwidth and drive to work on these areas. Both properties and threads have been presented at committee meetings, but then their authors for whatever reason did not follow through and pursue them.I think it's a shame that properties and threads aren't being actively worked on in WG21/J16, but like every other proposal someone has to be willing to invest the hard work to write and promote it and to convince busy committee members why it should be in the standard. I agree with Bjarne that properties should be in the language, not because they are a core language feature (they are not and they can be simulated) but because they are pervasive, and language support does give better ease of use than simulating the feature in a library (possibly with compiler magic-assisted types, where the compiler knows about special types and uses them as keys for code generation).FWIW, my understanding is that Borland intends to participate in C++/CLI and we sure welcome their input on properties in particular. Note that their approach has some C++ syntax extensions too.I'll respond to the other syntax question, particularly ^, in another blog entry.
  • Anonymous
    December 04, 2003
    I believe it is a mistake to drop the __ extension format because you think it is ugly. It is the accepted way to add keyword syntax extensions to C++, and clearly shows that the keyword is not a C++ standard one. Needless to say it also minimizes clashes with identifiers and macros.Some of your comments above regarding this are just plain silly:"Oddly, numerous programmers find the former more attractive. Particularly after the 2,000th time they type __gc."So they type 'ref' 2000 times instead. What a big improvement !For properties:"property int Length { int get() { return len; } void set( int i ) { len = i; } }"As if:"__property int Length { int get() { return len; } void set( int i ) { len = i; } }"would somehow be horrible instead !Finally your initial comments about ugliness, and C++ programmers leaving MC++ for other .NET implementations because of it, is really absurd. Nobody is buying that sort of argument, as if a computer language is a popularity contest in aesthetic appreciation.
  • Anonymous
    December 04, 2003
    >>I believe it is a mistake to drop the __ extension format because you think it is ugly.<<I would too. We used __ extensions in our first two releases for all the reasons you gave. We're dropping it, not because we think it's ugly, but because programmers keep complaining about it.The __ wouldn't be so bad for something like property. Other cases, like __gc, were more common, so much so that programmers did give and continue to give lots of negative feedback. (BTW, the case I had in mind wasn't the __gc on class declaration,s but on pointers, and there it goes to ^, not ref.)
  • Anonymous
    May 24, 2004
    Why don't we all just drop C++ for all new projects and adopt C#? It's an easy and painless transition and none of these issues would be present.