Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

GoingNative 3: The C++/CX Episode with Marian Luparu

Download

Right click “Save as…”

This is the C++/CX episode - everything you ever wanted to know, but were afraid to ask...

C++/CX language design team member Marian Luparu sits in the hot seat to answer some questions (a few from the GoingNative community - thank you!), draw on the whiteboard and demo some code. It's all about C++/CX. Tune in.

Table of Contents (click time code links to navigate player accordingly)

[00:00] GoingNative(); //Welcome. Diego spreads the news.

[06:05] Charles interviews Marian Luparu (Whiteboarding included)

[43:04] Marian Luparu demos some C++/CX and C++

[58:37] ~GoingNative(); //Charles and Diego recap. Don't fear the hat.

We really want to hear from you, so please tweet feedback to @C9GoingNative (follow us!) and send your requests, ideas, complaints, praises, hate mail, and love letters to C9GoingNative at hotmail com. We will read and respond to all messages! That's how we roll, brothers and sisters. If you are a Facebook user, then please join our C9::GoingNative Facebook group.

Go native!

Tags:

Follow the Discussion

  • Hey Charles, thanks for the shout out!

  • It would be very cool if VisualStudio could analyse C++/CX code for circular reference counts. Apple's Instruments tools for XCode does this for Objective C.

  • The audio and video of High Quality MP4 format not sync, delay a little bit.

  • Another great talk.  Wink

  • Richard Anthony HeinRichard.Hein Stay on Target

    Great show. Smiley  It was good to hear how things work and see it on the whiteboard; CX makes a lot more sense now.

  • @Marian Luparu
    Using these language extensions makes the source code locked to microsoft's compiler.
    So using gcc with superior c++11 support can't be used.

    Why did you not make a COM framework instead ?

    Many companies frown upon lock-in languages extensions and stays away from them. 
    If i understand C++/CX correctly, you must it to get access to metro stuff, so companies are forced to use the lock-in language extensions..
    Did you not consider the lock-in effect or was this planed ?

  • C64C64

    @Mr Crash: These C++/CX languages extensions are meant to be used only at the boundary; inside your C++ modules you can happily use ISO C++.

    And if for some reasons you don't want to use language extensions (or can't/don't want to use C++ exceptions), you can use pure C++ with WRL. And COM can be programmed in pure C as well (write your own v-tables... woow Smiley it can be a great learning experience, you may want to start from here.

     

  • JedrekJedrek

    You didn't call delete at the end of the presentation.

  • CharlesCharles Welcome Change

    @reply to Jedrek: We didn't need to -> we ref new'd and used hats, man Smiley This is the C++/CX epidode, so we get automatic ref counting and smart pointers...

    C^

  • CharlesCharles Welcome Change

    @reply to C64: Precisely!
    C

  • GlenGlen

    Great video guys, I hope to see more C++/CX videos because I'm still trying to get sold on C++/CX and hearing views of others about C++/CX, both for and against, helps evolve my opinions on it. Currently, I'm in the against camp, but please don't take my comments below as a negative relfection of the video - the video was great.

    I struggle to be sold on C++/CX. It seems others are too. My issues are not about the technical merit of C++/CX. It seems a great piece of technical work.

    However, I feel negative towards it on other grounds. Here's my reasons:

    If I constantly kicked you in the leg, would you thank me for selling you a new bandage every day? C++/CX appears to be yet another bandage I "need", but only because MS keeps kicking me in the leg. In that context, the best solution I really need, is for MS to stop kicking me, not to keep selling me bandages.

    Why do I say that? Well, once upon a time:

    I had Win32, a wildly successful API, but not the most friendly because it was C, and not C++. It had no destructors, so could easily leak.

    Then I had MFC, it was better, but being just a wrapper for the C Win32 API, it wasn't modern C++ or API design.

    Then we had COM. Object based, but hardly useable and hardly C++, just IDL and a vtable. In reality, it was even less friendly than C.

    Then we had .NET, good try, but it was slow and hardly useable from C++. It basically gave C# all that C++ ever wanted, but it took away all that C++ ever had. I needed .NET only because COM was so bad and C#/.NET got rid of COM for me but gave me a resource hog.

    Then we had C++/CLI. which gave me C# within C++, but I didn't want to go the slow world of .NET where I only went because C++ had been neglected in its tool support. I also didn't like having two concepts of class to keep in synch.

    Now we have C++/CX, which gives me COM within C++, so I can escape C# and .NET, and so C# can do the same! But only to be trapped by WinRT and Metro instead, and it's still COM and not straight C++! Now I have 3 concepts of class.

    Hmmmm

    Where in that great mass of development is a simple ISO C++ API? I don't see one! Now I realise I never had one!! Where in this does MS deserve my thanks!? (and that's without even mentioning the C++11 language features that we know are in the post. oops.).

    If you look at all that mass of MS development, it does very little for a C++ developer other than just create more and more interface churn and take things away only to replace them with something else with problems. MS are masters of this.

    These technologies don't add sufficient value to straight C++ development apart from making C++ code available to other languages that are unable to stand on their own and causing C++ to become infected with their features that C++ thus far chose to avoid for itself, like GC or ref counting. Which is why they aren't in the language yet already. If they were, I'd have less objections, but that's just one more thing until then.

    The most appealing API produced so far has been PPL and C++11 makes that even better.

    But the bottom line is:

    * I don't want to use C. It has no destructors.
    * I don't want to use COM. It is too hard.
    * I don't want to use C# (it's not bad), but I don't need GC, and C++ templates are handy, deterministic destructors are great, and r/value move operations are brilliant!
    * I don't want to use C++/CLI, because .NET is slow and a memory hog. .NET can come to me, I don't want to go to it.
    * I don't (yet) want to use C++/CX because I still don't like COM, or want another notion of component beyond C++ class. Nor do I feel sure about WinRT or what Metro licensing will be or want the walled garden that any of it might mean.

    I also hear people keeping talking about "borders" like its no big deal, like C64.

    C++/CX is a component technology. That's its name: Component eXtensions. It doesn't mean you just call some C++/CX api like Metro and wrap it with ISO C++.

    It means you cut up your own applications too, into little WinRT components so those can be exposed. Essentially, you don't just wrap someone elses code, you will be breaking up and wrapping your own code too!!

    Don't think borders where you wrap big boxes. Think borders where you wrap jigsaw puzzle pieces. Not fun!!

    C++ *already* has a notion of the Component, it's called the class. If you want to create a second notion of class, go for C++/CX. If you want a third, do C++/CLI. It will mean you create a one to one mapping/wrapping of your C++ class to a C++/CX or C++/CLI class for every component you use or expose.

    Is that what you want? So far, until I am informed otherwise, I don't want that. I want to write classes, not wrappers.

    Until I hear some opinions that change my viewpoint, which is what I am soliciting for, I don't want C++/CX. I want ISO C++. not "some other standard" that nobody else will adopt. I haven't seen C++/CLI fly far beyond Windows and I doubt C++/CX will either as things stand.

    C++/CX (why use WRL?) is a great technical solution, don't get me wrong, but right now, it's solutions to Microsoft problems, not mine. I don't want to spend my life wrapping up C++ for everybody else. I don't have to wrap anything if I use C#. It's 100% transparent. That's how C++ should be used.

    Bottom line: We need to stop the interface churn and redefinitions and make the tools generate the C++ -> C# AND C# -> C++ wrappers or whatever it takes, so that we aren't creating layers and layers of interface redefinitions by hand. It needs to be transparent so that I only write only ONE class definition - a C++ standard one - and the tools perform the magic to make that usable to every other languaage and vice versa. I don't want to have to use a ^ or a % to do it or require GC - unless it's in the C++ standard.

    That's my starting point. I ask people to try hard to convince me otherwise because this stuff has to be hardened by fire to proove its worth. I'm not looking to cause offense to anyone. Thanks.

  • C64C64

    @Glen: "C++ *already* has a notion of the Component, it's called the class."

    That's wrong. A C++ class is not a "Component": you can safely use a C++ class in a very constrained way.

    e.g. If you build a C++ DLL and export C++ classes from it, and if you throw C++ exceptions from the DLL, for the client to safely use these "C++ classes components" the client itself must be written with the same C++ compiler and the same flavor of the CRT/STL.

    For example: if you have STL classes at the DLL interface boundary, and the DLL is built with VC9 and CRT dynamically linked and with some settings of _HAS_ITERATOR_DEBUGGING (or the more modern _ITERATOR_DEBUG_LEVEL for VC10) and the client is developed with the same VC9 compiler but different _HID, then things got broken, because the memory layouts of the STL classes in the .EXE and the .DLL are different: so the DLL's "std::vector" is different from the EXE's "std::vector". What a fragile mechanism! And we are speaking of DLL and EXE built with the same C++ compiler... imagine with different compiler versions!

    (And with C++ new/new[] and delete/delete[] there are also problems in allocating and freeing memory across module boundaries; and even if you don't explicitly use new/new[]/delete/delete[] in your C++ code, they can be called indirectly in the implementation of other classes like STL containers, std::wstring or smart pointers at the DLL interface boundary.)

    A real Component should be much more robust than that. In fact, this robustness is achieved with COM: you can build COM components with VC<version X> and consume them with VC<version Y> safely (e.g. you can safely use legacy COM components written with VC6 or VC8 inside a client code developed using VS2010). Or you can even build COM components with language L1 (e.g. C) and consume them with language L2 (e.g. Visual Basic). That is what a Component is.

    As a bonus very interesting reading, consider this:

      If the shell is written in C++, why not just export its base classes?

     

    In a C++ project, I can happily write all my classes in ISO C++, I can happily use STL classes inside, and then, only at the boundary, I can use COM to offer to my clients a robust Component-based interface. If we want to build some Components using C++, and we have a team of N C++ programmers, only one programmer needs to know COM, to build the COM-based Components interface; all the remaining (N-1) C++ programmers just need to know ISO C++, and can ignore COM.

    To build COM components in C++, the best way right now was using ATL.

    Then Microsoft evolved the COM component technology introducing WinRT, and then they offered two ways to build those components (and to consume them as well): WRL and C++/CX.

    I find nothing wrong with that: just use the right tool for the job.

    Inside my C++ projects I just use normal C++ classes, e.g. to store strings I use std::wstring (ISO C++) and not Platform::String^ (C++/CX). I'd use Platform::String only at the boundary. Using Platform::String^ all over the place in C++ projects instead of std::wstring would be just plain wrong: C++/CX's Platform::String is only for the boundary.

     

    PS: As a side note, it would be great if Microsoft could offer an implementation of C++/CX to target also ordinary COM Windows 7 desktop development (instead of Win8 WinRT Metro apps only), as a more productive and simpler tool than C++ with ATL.

  • new2STLnew2STL xkcd.com

    @C64: Nice explanations. I loved that article of The Old New Thing.

    One of things that helped me to assimilate better about language extension and components was when I worked with Borland Delphi (and C++ Builder) years ago. Their component library and language extensions are also mean to be used only at the border and interchangeable for both languages (Delphi and C++). Reading about components and their design decisions worth the time. One also can look at computer science theory books and articles (COM, CORBA etc) Wink

    Making a component in RAD was pleasant and this is the why I'm excited with CX Big Smile

    The right tool for the job.

  • GarfieldGarfield

    @Glen -- good analysis. I think the real reason for frustration C++ developers feel is the fact the Microsoft keeps emasculating C++ in order to satisfy all other food group languages (with C# at the top). It's kind of schizofrenic approach because C++ is the most powerful, the most elegant, the most productive language, without which all those food languages couldn't even exist. It used to be the other way around, but unfortunately the food group became prevalent in the last decade with its pointer semantics and garbage collection, which are largely at odds with good C++ practices targeted at value semantics and generic design. They say it’s only about a border. I like that “only”, as if it were a small stuff. But I say, why should C++ be stripped naked to cross the border? – Let the food group go through the contortions, let C++ march in its glorious garbs. I really don’t understand “going native” campaign, because there is nothing “native” about it. Until MS understands the place of C++ and removes those food group fetters, Windows will continue to be a hostile development environment for C++ development.

    @new2STL: I used Borland/Codegear/Embarcadero C++ Builder. Their VCL library is absolutely nothing like MS extensions. Yes, there are limitations what you can do with VCL classes, and yes, there are “property” and “closure” extensions, but otherwise your code is fully C++, you hardly notice the extensions. VCL is actually a good example how to marry C++ with food languages with the least damage to the former. Had MS came up with a similar C++ library, it would have been a great success. Unfortunately, at present we are left to decide which is the lesser abomination C++/CX or C++/CLI or COM or WRL.

  • new2STLnew2STL xkcd.com

    @Garfield: But I was talking about the understanding (feeling) to make additions to the language in order to achieve objectives and not a syntax parallel of each other. In fact, the VCL has nothing to do with the extensions of MS but with proprietary extensions from Borland (now Embarcadero)

    What I was referring earlier is to the concept of modules, the modules can export classes and interfaces, which can be written in both Delphi or C++Builder (see I don't write C++ alone cause it is C++ with Borland extensions) and consumed by both. What I see happening today is what many of the so-called "Puritans" condemned Borland for extensions to Pascal in past. Also remember that there is not only the visual components in the VCL. I once implemented a wrapper for a measurement hardware in two phases: first wrapped the driver dll with C++ (pure) classes and then wrapped a non-visual module (component) for integrate it on C++Builder/Delphi.

    I do not understand the excessive anger of the people about the extensions of VS because the extensions will only achieve explicitly code going to interact with the core OS. In fact on the codes I've worked until today, VS extensions have minor impact if none at all. C++/CX is only trying to make programming productive (fast and fluid  Tongue Out ) and removing the boilerplate but if one want no extensions at all they're already reiterated that you can use full WRT (wich ref, '^' etc are translated into). Or you can still make your killing libraries and let another people do the 'border wrapping' Big Smile

    >why should C++ be stripped naked to cross the border?

    See the post of C64 in special about   If the shell is written in C++, why not just export its base classes?. Also have of the videos from C++&B, but for shortening name mangling, when on a future version of C++ they resolve the nm plus add an ABI for exporting components then will be the day C++ will not need be "stripped" on cross the border Wink

  • GarfieldGarfield

    @new2STL, I think there are several wrong assumptions made by MS in every iteration of their "managed" C++, and for that reason I don't think C++/CX will have higher level of satisfaction or live any longer than its predecessors.
    Firstly, that C++ developers are interested in interoperability with other languages, whether exporting to or importing components from other languages. Some might, great majority -- couldn't care less. Secondly, that C++ developers absolutely need stable ABI. It's one of those nice to have, but not really necessary features. Given the choice of standard C++ without ABI and emasculating C++ with ABI, I strongly believe the majority would choose the first. I never complained because I recompiled and shipped all my DLLs with the applications when compiler or libraries have changed (I even export functions with C interface when necessary), it's a small price to pay to stay with the standard. But I'm disappointed with every generation of emasculated C++ from MS that "solve" ABI problem. Thirdly, I don't really like the "branchy cranberry" class hierarchies, especially single-rooted. It stinks when everything grows from some "Object" class, it stinks to see all those pointer conversions. I don't want object-oriented design in Java or C# sense, I don't want inheritance and pointer semantics. I want a modern event-driven C++ design with no gratuitous hierarchies, with value semantics, with std::function for event handlers, with standard containers, standard strings, etc. etc. And if somebody wants to add extensions to the language, they are welcome to suggest them to the C++ standardization committee, then they will have the burden to prove they are useful for the language at large.

  • jalfjalf

    @Glen: thank you, for expressing this so mcuh more clearly than I could have. I feel very much the same way about C++/CX. I'm still trying to make up my mind, and I'm not yet quite convinced that it was the right way to go.

    @C64 (and more generally), I'm having a hard time imagining how this "C++/CX is only at the boundary" thing is going to work out in practice. I suspect that it's going to "bleed" into your general code base. Why wouldn't it?

    In theory, windows.h should only be used at the boundary too. How many applications managed to do *that*? How many Windows applications do *not* have DWORDs and HANDLEs all over their code?
    If it is reasonably *possible* to limit C++/CX to the boundary code only, then that's great, and as it should be. But I suspect that it's a noble intention and a great thing to say to calm people's fears, but that in practice, it aint gonna happen.

    So Microsoft, I'd love to see some examples of this. Has anyone who worked on the language actually tried writing applications where C++/CX was only used at the "boundary" interop layer? Or did you just write your code with C++/CX all over the place because that was the most convenient? What were your actual experiences with this?

    In particular, the need to use special WinRT types instead of the ones that already exist seems worrying. As far as I know (I haven't looked closely at this), the WinRT String class gets mapped to .NET's String under the hood for .NET users. But C++ users have to use a new, proprietary string class throughout their application (or convert strings between two classes all over the place). Won't the easy way out be to use WinRT's string class all over, then? And when you do that, you've effectively turned you *entire* code base into C++/CX, rather than keeping it at the boundary only. Couldn't C++/CX have made a similar conversion implicitly (at least optionally)? When a WinRT component expects a string parameter, let me pass a `std::wstring`, and do the conversion internally? C++/CX seems to sit in an odd place where, on one hand, there's no clear separation between it and ISO C++, and on the other hand, it doesn't go *all* the way towards playing nice with C++, instead forcing the ISO C++ code to bend and submit.

    It seems like there's a huge disconnect in the whole "going native"/"C++ renaissance" thing. Microsoft thinks that we simply want native code (code that does not rely on the CLR), whereas what what their users are calling out for is primarily ISO C++. I've heard the "but C++/CX is all native, don't worry, there's no .NET in it" response from a lot of Microsofters, which just completely misses the point. I don't care if it's native or not, I care if it's C++. And so from Microsoft's point of view, C++/CX was a great solution because "hey, we're letting people write native code now", and when their customers see it, their immediate reaction is "what the hell, *another* proprietary language? Why do you have C++ so much?"

  • PFYBPFYB


    I am also non-plussed at the idea of using yet another language extension.

    C64, I take it that you have no problems with C++/CX:

    "Then Microsoft evolved the COM component technology introducing WinRT, and then they offered two ways to build those components (and to consume them as well): WRL and C++/CX. I find nothing wrong with that: just use the right tool for the job."

    I have a number of problems with C++/CX in particular, but in this post I will focus on just one point. Why, in the case of Microsoft, the right tool for the job is almost always another language extension? Why do they always have to butcher the language, the standards, the tools and the infrastructure built around these standards? Why??

    In the past 8 years, this is a 3rd extension to C++ that is being pushed on us:

    The first extension, managed extensions for C++ has already been declared dead and is no longer supported. At its inception, of course, that extension has been touted as the best thing since sliced bread. Of course, it wasn't all that great, thus it failed and has been buried.

    The second extension, C++/CLI is still with us, but has been largely neglected by Microsoft right after being introduced. C++/CLI is definitely a second-class citizen in the world of Windows development. First, of course, it goes without saying that nobody besides Microsoft supports it, thus you are locked to a single compiler and a single IDE. Then, debugging mixed-mode projects written in C++/CLI is terribly, unbearably slow. Developing in C++/CLI leaves you without Intellisense. Heck, you can't even do multi-targeting of .NET versions. Think about it, C++/CLI is supposed to be THE language for interop between native and managed worlds, the ability to target different versions of .NET is pretty fundamental for that, yet C++/CLI can't do it *while C# and everyone else can*!

    Now we have the third extension, C++/CX. Sigh... Microsoft never learns.

    Does anyone seriously believe C++/CX will still be with us and Microsoft will continue to work on it in, say, 5 years? Does anyone believe Microsoft will not abandon or freeze it in favor of yet another flavor-of-the-month language extension / "cool" development thingy in that time? Contrast that with C++11, which you know will be there, supported and used.

    C++/CX is an unnecessary, temporary thing. I wish Microsoft didn't do it and instead worked on improving WRL or some other C++ library so that using WinRT from ISO C++ would be as easy as doing that from other languages. To bring the point once put forward on another thread by another poster here, we were promised a fluid and fast way to use WinRT from a language of our choice. A language of my choice is ISO C++. What is the fluid and fast way to use WinRT for me? Neither raw COM nor WRL qualifies as fast and fluid. C++/CX is a different language. The answer is: there is no fluid and fast way to use WinRT for an ISO C++ developer. And this says it all.

  • CharlesCharles Welcome Change

    @PFYB: Thanks for expressing your opinions. Keep them coming.

    Did you watch the interview with Marian? We discuss:

    1) The reasoning behind going the extension route

    2) What the extensions are and why they are what they are

    3) When to use C++/CX

    4) The meaning of "just use it at the boundary" and how thin this boundary can be

    5) The fact that you don't have to use C++/CX at all...

    C

  • I honestly don't mind Microsoft making C++/CX, in the general sense. Domain-specific language extensions are fine, and using them within those domains is fine.

    My problem is that Microsoft spent precious compiler developer time on C++/CX that wasn't spent on C++11 support. Which is why VCNext's C++11 support is barely improved from VC10. No uniform initialization. No initializer lists. No varadic templates. These are major C++11 features that Microsoft just decided not to bother even trying to support. We won't see support for them until VCNext+1, if then.

    Microsoft has shown that they don't have a commitment to the C++ language itself. That's my problem.

  • PFYBPFYB

    +1 to Alfonse. I do mind having language extensions, I think C++/CX is a net loss on its own, but I would be much less vocal on this if Microsoft delivered on C++11. That Microsoft have chosen to spend resources on a language extension INSTEAD of implementing the C++11 standard makes it that much worse.

    @Charles: Yes, I did watch the interview. I can answer point by point, if you want, but in general:

    * I am totally unconvinced that developing a language extension was warranted, you could have done everything using ISO C++, generating metadata if you absolutely have to,

    * I know about WRL, of course, I wish you spent more time on that, because right now it leaves a lot to be desired, same with raw COM - I am fine using it and just wish you spent more time tying WinRT to raw COM without involving language extensions,

    * I cringe whenever I hear this "only at the boundary" talk, because the boundary is hugely important (as an experiment, look at the list of features for any modern application, I predict that at least half of them, perhaps more, will touch "the boundary" in some way).

    That's it.

  • BongoBongo

    I fully agree with the long comment of Glen.

  • C64C64

    @jalf:


    @C64 (and more generally), I'm having a hard time imagining how this "C++/CX is only at the boundary" thing is going to work out in practice. I suspect that it's going to "bleed" into your general code base. Why wouldn't it?

    In theory, windows.h should only be used at the boundary too. How many applications managed to do *that*? How many Windows applications do *not* have DWORDs and HANDLEs all over their code?

    jalf: When you write MFC apps, it makes sense to use CString in the MFC code, because it is well integrated with the framework. And CString (which is platform specific) offers better support for *useful* stuff like loading strings from resources, which lacks in std::wstring. And this is because std::wstring is cross-platform, but loading a string from string table resource is Win32 platform-specific stuff.

    So, both CString and std::wstring are doing their jobs well: one is well integrated and convenient to use for Windows-specific code, the other works well for multiplatform code.

    The fact that you use MFC for the GUI (and CString here), doesn't mean that you have to use CString all over the place in your C++ code: you can use STL containers and std::wstring in the core non-GUI part of your app, and make it portable to other platforms.

    The fact that some apps have DWORD's and HANDLE's all over the place can be a bad design decision and bad implementation technique, but you can't blame Microsoft for poor software engineering practices of some 3rd party developers. Those raw HANDLE's could be wrapped in C++ RAII classes, and not exposed outside.

    If you code for Windows in C++, of course you have to have some layers of code which interact with Win32 API and manage DWORD's and HANDLE's, but you can wrap them in C++ classes and hide these implementation details to the other layers of code.

     

  • C64C64

    @PFYB:


    C64, I take it that you have no problems with C++/CX:

    Yes, I don't have problems with language extensions for platform specific code.

    I can use ISO C++ for the most part of the app, and use the language extensions for platform specific stuff, if it makes me more productive.

    And, again, if you don't want to use extensions, there is WRL.

     

    I have a number of problems with C++/CX in particular, but in this post I will focus on just one point. Why, in the case of Microsoft, the right tool for the job is almost always another language extension? Why do they always have to butcher the language, the standards, the tools and the infrastructure built around these standards? Why??

    Probably because the standards can't cover 100% special cases of platform specific code?

    It seems to me that QT, which is multiplatform, does have some kind of "extensions" to address some problems that standard C++ can't address in a productive/convenient way: e.g. QT has the "moc" compiler and makes use of several macros to enrich the C++ language.

    In my practical view of programming, if a language extension makes me more productive for writing platform specific code, it's OK to me.

    For what I've seen so far, the "fast and fluid" way of programming Metro in native code is using C++/CX. WRL uses standard C++, but seems to me less productive than C++/CX.

    What would be an ISO C++ alternative to C++/CX? Would it require using preprocessor macros? Would it require a separate compiler (kind of like MIDL) for metadata or other platform specific stuff?

    I'm not sure this would be better than a platform-specific language extension like C++/CX.

    Nevertheless, let's enjoy each other's viewpoints.

     

  • PFYBPFYB

    @C64: Very simple:

    "So, both CString and std::wstring are doing their jobs well: one is well integrated and convenient to use for Windows-specific code, the other works well for multiplatform code."

    The problem is not that either CString or std::wstring are not doing their job. The problem is that they are arguably doing the same job yet they are two different classes. If you were designing MFC today, would you reuse std::wstring or would you invent your own string class? Easy question, right? Of course, you would use std::wstring. It's the same with WinRT.

    Everyone understands the concept of splitting code into modules which have separate responsibilities. The problem is, making a separate class representing "a string for the GUI subsystem" instead of just using a generic string class does not add a lot of value. Why not just use the latter? Same with the syntax. Why have "a super-smart pointer to a regular COM object which is just so cool it has to use a hat"? Why not use the traditional smart pointer?

  • C64C64

    @PFYB:

    +1 to Alfonse. I do mind having language extensions, I think C++/CX is a net loss on its own, but I would be much less vocal on this if Microsoft delivered on C++11. That Microsoft have chosen to spend resources on a language extension INSTEAD of implementing the C++11 standard makes it that much worse.

    I imagine that if Microsoft had not delivered C++/CX, then several people would have said: "Oh, programming Metro in C++ with WRL is hard: is kind of like COM and ATL; let's use C# for that, it's much more productive." So, I think C++/CX was a good move to offer a native development tool for Metro.

    However, I'm also kind of disappointed because C++11 support in VC11 is insufficient. I'd not expected full C++11 standard compliance; but some nice things like variadic templates or range-based for loop would have been a very nice touch. But let's hope in a hotfix or serivce-pack 1 Smiley

     

     

     

  • C64C64

    @PFYB:

    "If you were designing MFC today, would you reuse std::wstring or would you invent your own string class? Easy question, right? Of course, you would use std::wstring. It's the same with WinRT."

    The problem with std::wstring and WinRT is that WinRT strings have to cross module boundaries, kind of like BSTR's of COM (so, they need to use a common memory manager): std::wstring can't do that. So you need a new ad hoc string class (to wrap a WinRT string handle - HSTRING? - ) for WinRT.

    I think a similar thing happens for WinRT C++/CX collections (<collection.h>): standard STL collections can't safely cross module boundaries (and C++ exceptions - which they use - can't either), instead the collection classes implemented in <collection.h> can.

    Both Platform::String and <collection.h> classes can be used only at WinRT boundary; std::wstring and STL containers in the rest of the code.

     

  • PFYBPFYB

    @C64: Thanks for the answer (we cross-posted). Yes, let's enjoy each other's viewpoints.

    [PFYB: "Why, in the case of Microsoft, the right tool for the job is almost always another language extension? Why do they always have to butcher the language, the standards, the tools and the infrastructure built around these standards?"]

    "Probably because the standards can't cover 100% special cases of platform specific code?"

    Of course, the standards can't cover 100% special cases of platform specific code, but why the solution to this is to add a language extension? There are other ways to cover special cases of platform specific code. Why not, say, write a library?

    "What would be an ISO C++ alternative to C++/CX? Would it require using preprocessor macros? Would it require a separate compiler (kind of like MIDL) for metadata or other platform specific stuff?"

    Yes, macros, base classes, as well as tools (or new logic in the existing tools) to generate and use metadata.

  • PFYBPFYB


    @C64:

    "The problem with std::wstring and WinRT is that WinRT strings have to cross module boundaries, kind of like BSTR's of COM (so, they need to use a common memory manager): std::wstring can't do that."

    I understand that WinRT strings have to cross module boundaries and that std::wstring can't do that. I also understand that C++ is a low-level language and thus we have to have means to use the low-level WinRT strings as they are. The problem is with the way MS tackles the use of WinRT from C++ at the high-level. Why, instead of having Platform::String^ and a plethora of new syntax and rules in the new language extension, which is what we have as the high-level now, not have std::wstring and traditional C++ classes and smart pointers?

    Imagine doing this:

    #import "winrt.<subsystem1>.dll"
    #import "winrt.<subsystem2>.dll"

    ...and having it generate C++ classes with shared_ptr<IWhatever> and wstring. Why can't we have this instead of C++/CX?

  • CharlesCharles Welcome Change

    @PFYB: WRL is largely undocumented at this point. This will change, of course. Stay tuned.

    In terms of the need for extension, can you provide some more information as to why you think it would have been possible to do in ISO C++ (this would amount to it being a library and Marian explained why the lib approach wouldn't work...). Just want to understand your position better.

    All, keep it coming. There's no way to learn without listening.

    C

  • Michael PriceMichael Price

    @PFYB
    "Imagine doing this:

    #import "winrt.<subsystem1>.dll"
    #import "winrt.<subsystem2>.dll"

    ...and having it generate C++ classes with shared_ptr<IWhatever> and wstring. Why can't we have this instead of C++/CX?"

    Because, then someone would be able to instantiate a non-reference-counted object of type IWhatever. Hello memory leaks.
    Now, this could be worked around by using the named constructor pattern, but what about when the coder has to implement a class to pass to a component of WinRT? It cannot be enforced. In C++/CX, reference counting is a part of the contract of a ref class. There is NO other way to instantiate them, and this is a good thing.

  • GarfieldGarfield

    @Michael Price: "Because, then someone would be able to instantiate a non-reference-counted object of type IWhatever. Hello memory leaks."

    It's been a long standing philosophy of C++ to let people jump off the cliff if they want to. You offer safety nets as long as they don't impose unreasonable constraints on those who know what they are doing. Compare that with Borland/Codegear VCL. Yes, VCL classes aren't fully C++, most of them can only be used as regular pointers (not hats) and can potentially be misused. Has anybody heard horror stories about it? I don't remember anything significant since 1996 when the first version was released, and unlike 3 iterations of "managed" C++ and general dissatisfaction, VCL is largely unchanged and enjoys favorable opinions. I'm not saying MS should imitate VCL, I believe there are far superior solutions, but I'm saying that MS continues treading the same turf with the same methods and the same results. Tell me what is it?

  • GarfieldGarfield

    @C64: "The problem with std::wstring and WinRT is that WinRT strings have to cross module boundaries, kind of like BSTR's of COM (so, they need to use a common memory manager): std::wstring can't do that."

    Who said std::wstring can't cross the boundary? There are two ready solutions in C++: overloading or displacing "operator new" and/or providing custom allocators. Any inconvenience caused by those two methods pale in comparison with non-C++ String type. Even making interface taking wchar_t* and prohibiting cross-boundary construction/destruction would be a better solution. It's a bad design having objects without owner anyway, so either pass a copy or move with rvalues -- don't throw the hats all over the place.

  • C64C64

    @Garfield:

    Who said std::wstring can't cross the boundary? There are two ready solutions in C++: overloading or displacing "operator new" and/or providing custom allocators. Any inconvenience caused by those two methods pale in comparison with non-C++ String type. Even making interface taking wchar_t* and prohibiting cross-boundary construction/destruction would be a better solution. It's a bad design having objects without owner anyway, so either pass a copy or move with rvalues -- don't throw the hats all over the place.

    I've already written on problems on passing STL stuff across module boundaries.

    And note also that STL stuff including std::wstring can throw C++ exceptions, and they can't safely cross DLL module boundaries either (so, even if you use a custom common allocator for std::wstring, e.g. CoTaskMemAlloc(), then there are other problems to be fixed, like C++ exceptions flying out of DLL's, or structure of STL containers changing with different compiler versions and _ITERATOR_DEBUG_LEVEL values, etc.)

    Moreover, I consider the pure C style of raw wchar_t* a bad design, a move backward in the 1990's Smiley  passing a pointer to preallocated buffer + the buffer size, like say with ::GetWindowText()...? And maybe return codes or call ::GetLastError() to get error information? No, I do prefer the modern object-oriented exception-based C++/CX approach.

     

  • GarfieldGarfield

    @C64: "And note also that STL stuff including std::wstring can throw C++ exceptions, and they can't safely cross DLL module boundaries ..."

    As I suggested, don't pass the objects across the boundary if you can't handle exceptions, make a copy on the other side, or move, or swap, and return them the same way. You can even serialize the object to pass it through the boundary and construct them on the other side. People were crossing DLL boundary long before COM/.NET/whatnot appeared staying within standard C++, it's not like it's a new problem.

    "Moreover, I consider the pure C style of raw wchar_t* a bad design"

    Bad design? How about the cure for bad design? No, really, I think System::String^ is much worse design. Heap allocated objects without clear ownership, like those traveling with hats is a bad design. Have you noticed when std::unique_ptr was finally available how shared_ptr became a lot less useful? People found they used the latter only because the former wasn't available. In reality, there aren't many good solutions that require sharing. Shared (ref counted) pointers already smell of design problems.
    Again, there is nothing terribly wrong about passing wchar_t* zero terminated strings, it's simple to get pointer to a buffer, const wchar_t* cstr = mystring.c_str(), it's easy to make a copy std::wstring mystring(cstr). It's been used for ages. Built-in types are your friends -- they never throw.

    Of course, I don't want to trivialize the issues suggesting that all problems can be solved in short discussion thread, C++ standard doesn't have notion of DLLs, modules, ABI. The solution is still to keep standard C++, achieving as much as possible with libraries, probably using external tools, designers, code generators, macros, attributes, etc. to fill the gaps. Just like other existing frameworks do. The worst solution is to mangle C++ by adding these extensions, which ironically doesn't mean extending the language. In reality as soon as you are using these extensions you are constraining the language, imposing upon it foreign architecture coming from languages with pointer semantics and garbage collection. I wish Java/C# were never created, because we have a lost decade in software industry. Free C++ from the burden of C# architecture and I'm sure you will see how to do it right.

  • C64C64

    @Garfield

    @C64: "And note also that STL stuff including std::wstring can throw C++ exceptions, and they can't safely cross DLL module boundaries ..."

    As I suggested, don't pass the objects across the boundary if you can't handle exceptions, make a copy on the other side, or move, or swap, and return them the same way. You can even serialize the object to pass it through the boundary and construct them on the other side. People were crossing DLL boundary long before COM/.NET/whatnot appeared staying within standard C++, it's not like it's a new problem.

    Crossing DLL boundaries with standard C++ is very constraining.

    One possibility is to only let C++ abstract interfaces cross the boundaries... and then you start reinventing COM (which is interface-based).

     

    "Moreover, I consider the pure C style of raw wchar_t* a bad design"

    Bad design? How about the cure for bad design? No, really, I think System::String^ is much worse design.

    [...]

    Again, there is nothing terribly wrong about passing wchar_t* zero terminated strings, it's simple to get pointer to a buffer, const wchar_t* cstr = mystring.c_str(), it's easy to make a copy std::wstring mystring(cstr). It's been used for ages. Built-in types are your friends -- they never throw.

    Passing wchar_t *, raw handles (HWND... HANDLE... H<something>...) it's so 1990's... Yes, it's possible to have pure C interfaces at the boundary (like lots of Win32 API's do), but I prefer a modern object-oriented interface, and so I welcome language extensions if they make it possible in a productive and programmer-friendly way.

     

  • PFYBPFYB

    @Charles:

    "In terms of the need for extension, can you provide some more information as to why you think it would have been possible to do in ISO C++ (this would amount to it being a library and Marian explained why the lib approach wouldn't work...). Just want to understand your position better."

    Sure.

    Very simply, my position is that there is no need to have yet another language extension, because one can achieve everything this extension provides, including ease-of-use, by using ISO C++ and some support from tools that generate and use C++ code and / or metadata.

    That's pretty close to saying that everything can be done by using a C++ library, but not quite equivalent, as the source code for that "library" should, as I propose, at some point be generated by a tool. The generation of the source code (or even binaries) is, of course, nothing terribly revolutionary, we've had this for years with tools like TlbImp / TlbExp in .NET and features like #import in C++.

    With that, let's turn on to what Marian says in the video. He brings up three points as to why you went with a language extension:

    1. You really wanted the classes representing WinRT objects in C++ to throw exceptions instead of returning HRESULTs, eg, to have chain calls (GetX()->GetY()->GetZ()), etc. -- Good. That's not the first time we encounter this problem, we had the same problem with COM. Extend #import to cover WinRT: allow #import to take a WinRT module, parse its metadata, then use that metadata to generate corresponding C++ classes, rewriting method signatures so that instead of returning HRESULTs they return [out,retval] values. Done.

    2. You really wanted to preserve IFoo inheriting from IBar, even though in WinRT this merely means that QueryInterface'ing IFoo for IBar succeeds. -- Good. Have the C++ code generated by #import expose interfaces IFoo and IBar as inheriting from each other in the C++ sense, do the QueryInterface's in the implementation as necessary. Done.

    3. You really didn't want to force developers writing WinRT components to write methods in COM style, returning HRESULTs. -- Good. Interestingly enough, at this point Marian actually mentions #import, and says that this is where #import doesn't help. In the recent thread on vcblog Jim Springfield talks about the same thing. I get an impression that this point is *the* reason the team gave up on #import and concluded that they have no choice but to add new language constructs. So, is there really nothing that could be done here? Of course, not. Just do the reverse of what #import does and generate wrapper C++ code that is facing outwards. Eg, have a compiler option that would take the C++ code and generate wrapper classes for that code, turning methods returning whatever into methods returning HRESULTs, converting exceptions into HRESULTs, generating GUIDs for interfaces, etc. If you don't want to do this within the compiler, pack this functionality into a separate tool. This is so simple, it is amazing neither Jim nor Marian don't seem to ever acknowledge the possibility of that. The irony is that this also, at least to me, seems significantly easier to implement than C++/CX, since that requires doing only part of what you had to do for C++/CX (you have to parse the C++ code and generate / consume metadata, but you don't have to actually extend the language). Done.

    So, all three issues addressed. There are other issues like the ABI, having to suppress exceptions, etc, not brought up in this video, but so far, I didn't come across anything that couldn't be addressed by generating C++ code both ways, as above.

    In sum, it seems to me that the team didn't go far enough in trying to tie WinRT with C++ without altering the C++ language. You gave up far, far, far too easily. Generating C++ code both ways, for wrapping WinRT objects in order to use them from C++, and for wrapping C++ classes in order to expose them for WinRT applications or modules, would have allowed to do basically everything C++/CX does now. Wrapping both ways wouldn't also be all that different from what other languages are doing - I take it that .NET languages wrap both ways as well. As a result, C# developers use System::String and never see Platform::String^, they can pretend everything is garbage collected even though WinRT objects aren't garbage collected, etc. Why did you not do the same for C++??? Beats me.

  • PFYBPFYB

    @C64:

    "Passing wchar_t *, raw handles (HWND... HANDLE... H<something>...) it's so 1990's... Yes, it's possible to have pure C interfaces at the boundary (like lots of Win32 API's do), but I prefer a modern object-oriented interface, and so I welcome language extensions if they make it possible in a productive and programmer-friendly way."

    This is where we differ.

    If I were to choose between (a) passing raw handles and staying compatible with the ISO C++ standard, and (b) passing hat pointers to objects but using non-standard language extensions, I would choose the former. I'd rather write a couple of wrappers to make passing raw handles easier, but be able to use the standard C++ toolset, than go the other way.

    Hence, no C++/CX for me.

  • GarfieldGarfield

    I give up, I feel like my messages are lost on the other side of the boundary.
    The bottom line, I don't have much hopes that after 10 years of experimentation MS would finally create a reasonably good solution, it's still rehashing the same failed approaches. I predict 2-3 years from now MS will cheerfully announce they are done with C++/CX and offer the next iteration of the same. I hope some company, like Codegear/Embarcadero will wrap this unsavory design in close to standard C++ implementation as they always did. The third party solutions were always better and it looks like this trend will continue.

  • GlenGlen

    @Jalf: Thanks for the kind words and your balanced contributions to the various debates.

    @Garfield, welcome to the party! :)

    @C64: Thanks for your thoughtful reply. You are absolutely right in your technical explaination of the class/component problem space. However, I think you are mistaken to claim I am wrong when I said that "C++ already has a notion of the Component. It's called the class." Here's why:

    If you google the word "notion" used in my statement, you will find this definition:
    no-tion (noun): A *vague* awareness or understanding of the nature of something.
    Synonyms: idea - *concept* - conception - thought - mind - opinion

    Referring to that definition, you will see that I wasn't claiming that a C++ class and a Component (any of Microsofts definitions of them!) are exactly the same thing from a technical perspective. I was arguing that the C++ class is *vaguely* similar in *concept* to the Component.

    I stand by that and don't feel that to be wrong at all.

    The difference between us was your emphasis concluded with classes and Components being different (your emphasis is on the *vague* from "notion") and mine concluded with that they are different but *also* similar in concept i.e. equivalent. (my emphasis is on the *concept* in "notion").

    I don't want to lose that distinction because the "equivalence" (for want of a better word) is really important!

    @c64 and @others:

    If you think class and Component are so different, note that effectively C# only has one definition of class to support both class and Component, as did C++ until Microsoft introduced C++/CLI and C++/CX etc. to add more. not to mention the different pointer types required to support them!

    When you make a Component and a class different, *one has to still reach the other*. If that's not transparent (and it should be), that makes C++ developers chief "wrapper upperers" to the king! If that's my job, I'll quit - or get a new king. C# does not make you do this because class and Component are not surfaced in the language in an invasive way.

    Once you conclude that the class and Component are not just different, but *equivalent*, you should start to see why "the border matters" - because the border will be everywhere: not just at "the OS level", the Metro level, or any of the places people instinctively know they will need to wrap. It's at the Component level and when that equates to the class it means the borders are everywhere!! Plus all of those usual OS level places as well!!!

    IMHO, herb and C64 seem to underestimate the importantance of what this means in practice. I think it's huge.

    People will have a natural incentive to want to share/expose their *own* ISO C++ classes as Components so they can be used by the market - i.e. by other languages (like C# and Javascript). They may even be forced to do that, to support OS APIs (like Metro) or if MS insists on it through policy. So people will be incentivised, or forced, to put up their own borders. Everwhere. So they will.

    That means the neccessity will be for ISO C++ developers to put hand wrapped Microsoft classes and technology around *each* of their own ISO C++ classes to make them useful in the Microsoft world; and/or, put ISO C++ wrappers around Component classes they use to prevent the Microsoft extensions bleading into their main code base.

    Obviously MS think maintaining an ISO C++ class, a classic COM class, a C++/CLI class, a C++/CX class or a "whatever they dream of next week" class is a useful endeavor. I don't think its even viable. Even if it is, why does MS think that C++ developers want to be chief wrapper upperers to the king? What is fast or fluid about that? How is that productive for a C++ developer or a C++ renaissance?

    The maintainance effort (bye productivity) required to support ISO C++ classes and "other" component classes will cause some people to just forget about the cross platform (bye opportunity) ISO C++ one (bye standards) or eschew componentising their product to begin with (bye opportunity).

    Fusing a "Component Technology" into a language like C++ (in an invasive way) that already has a notion of Component is a mistake IMHO. It supports lock in (bye freedom) and other languages that fail to stand on their own (hellow slow coaches); allowing "them" to stand on our shoulders but not doing enough for C++ "us".

    In C#, most of this IS transparent, and the only Component to maintain is the class.

    Is any of this good for ISO C++ and is the complexity of any of it neccessary? Has any of this technology really proven itself and will any of it be here in 5 years?

    I see Component Technology as a bridging technology, that's "all" it does. If it isn't nearly virtually transparent, it isn't the right way to go. It shouldn't be invasive. C++/CX and C++/CLI aren't transparent, ref class, ^ and % are not transparent and wrapping is invasive and GC may be the same.

    In C# class and Component are the equivalent and the details are as hidden as possible - that shows it is possible and the right idea. C++ component technology needs to hit the same level of transparency in a standard way and I believe this to be possible.

    The C++ modules effort may further the right technology, but regardless there has to be other better ideas short of the proposition I see now to make Component transparent. I think the ISO C++ team (that includes us) need to be working on whatever the right bridging/component technology is to make Microsofts component technology transparent. If that can't be done the platform needs to go, not C++.

    So far, IMHO, C++/CLI and C++/CX don't achieve the goals I think they should for C++, just Microsoft, and are another dead end if thats all we get.

    Do keep trying to convince me otherwise, I am keen to hear the other views - or how about better solutions to this problem space (it does need a solution) if possible - that is being positive too.

    Thanks

  • KevUKKevUK

    @Charles: Thanks for the video. It has a nice flow and good amount of detail. That said, I watched with amazement at yourself saying over and over that C++/CX is no big deal, just a "ref" here and a hat there, and how it all is a very small extension. That's missing the point by quite a margin! The number of keywords in a language extension doesn't matter! A single keyword that you have to use is all it takes to turn a standard-compliant program that compiles in GCC or in a prior version of VC, into a non-compliant program that doesn't compile. PFYB is talking a lot of sense. Being able to use the standard C++ toolset is of paramount importance. Our codebases are huge, we do need a lot of tools to help us deal with the complexity of our code, designers, modelers, analyzers, documentation extractors, style checkers, you name it. These tools have expectations that the source code is standard-compliant! We do use more than one C++ compiler, too. I doubt any of these compilers besides VC (excluding existing versions - already a loss!) will support C++/CX in the foreseeable future!

    I don't know how to say it any clearer: The standards are important! Don't break them!

  • CharlesCharles Welcome Change

    @KevUK: Thanks, Kev. I understand.

    I guess my light-hearted commentary should be interpreted as "C++/CX is for use in writing simplifed native (COM reimagined) Windows 8 Metro Style applications with shareable components(shared across very different language boundaries....)."

    So, you wouldn't write a library in C++/CX and expect it to be consumable/usable (as intended...) outside of the context of WinRT. I mean, right? That seems to be pretty clear.

    Sorry if I made it sound like this is no big deal (the hats and refs, the extending of a standardized language...) Of course standards matter. They matter very much to us. You are absolutely right. The goal of this episode of GoingNative was to shed some light, real light, on why C++/CX exists at all. I trust that came through?

    C

  • GlenGlen

    @Charles

    The Component IS the platform (any platform, not just WinRT) because the Component IS the library and the library IS the platform.

    When we write a library, we want it to be consumable everywhere with the least effort neccessary.

    If C++ can't hurdle the library "border" transparently or be the border transparently, you cut off C++'s legs and give us two heads. That probably explains the extra hats!!!

    Seriously, there is no viable C++ in the world you describe, it is only C++/CX or C++/CLI, or whatever you come up with tomorrow.

    If that's the goal, admit it, but I don't support it.

    If that's not the goal, admit it, and lets fix it.

    When you write a library in C#, you write a library in C#, not WinRT.

  • CharlesCharles Welcome Change

    @Charles

    If C++ can't hurdle the library "border" transparently or be the border transparently, you cut off C++'s legs and give us two heads. That probably explains the extra hats!!!

    Smiley


    When you write a library in C#, you write a library in C#, not WinRT.

    You can't really compare a VM-based solution to a native one... Yes, the C# compiler team and CLR team had to do a lot of work to keep C# and .NET looking and feeling like C# and .NET for C# and .NET developers in their effort to support the WinRT programming model.

    C++, on the other hand, has a very different set of problems to solve if the goal was to make WinRT transparent to ISO C++ users (the C++ team did a LOT of work as well...). It's hard to know if this is really possible without too much added complexity at the composition layer (the code you have to write). Of course, there is a way for you to write ISO C++ and not C++/CX to build native WinRTobjects/components... We've already discussed this a number of times: WRL. If you want to expose your component to other components that aren't written in the same language, then it's much easier to use hats and refs than hand-rolling COM. 

    A big part of this C++/CX thing is to make your life easier when writing WinRT applications and components for Windows 8 Metro... Right? There's no evil plot to fork the language -> you only ever use C++/CX to write native apps/shared components that target a single platform. Right? Then again, that's exactly where you find this to be annoying and wrong. I understand that.

    I'm not arguing for or against anything. Just trying to help clarify the way it is.

    C

  • PFYBPFYB

    @Charles:

    I hope I clarified how exactly I think you could have implemented everything there is in C++/CX using straight ISO C++ in my previous post. If there is anything that is not clear about what I am saying, please ask and I will elaborate.

    With that, I am going to address a couple of points in your answer to Glen:

    "You can't really compare a VM-based solution to a native one..." [In terms of how they work with WinRT.]

    A VM-based solution differs from WinRT *more* than a native solution! A VM-based solution has garbage collection and compiles code from IL on the fly! Yes, the devil is in the details, but the fact that .NET languages can use WinRT seamlessly despite .NET being managed code and WinRT being native code, while C++ can NOT use WinRT seamlessly despite both C++ and WinRT being native code, speaks for itself. Yes, .NET and C++ differ a lot, but we, the developers who frequent this and other Microsoft sites, aren't total C++ babies, we know a bit on how to map platforms and concepts onto each other, we have a lot of practice doing that with COM and similar technologies, both Microsoft and non-Microsoft, and it definitely seems to us that Microsoft could have done the mapping of WinRT to C++ without altering the language, with roughly the same effort as was required for C++/CX, and with more or less the same results plus the standards-compliance. So, yes, .NET and C++ differ a lot, but the fact that .NET languages can use WinRT seamlessly and C++ can't does not exactly seem to speak to the fact that tying WinRT to C++ was somehow more difficult than tying WinRT to .NET. This seems to be more about .NET guys in Microsoft caring more about preserving their languages than C++ guys.

    "the C++ team did a LOT of work as well..."

    Yes, absolutely, they did a lot of work. The problem is: the C++ team forgot they are the C++ team and did their work for a different language. The work they did does C++ more harm than good! The C++ team absolutely could do what they wanted to do without altering the language, but they seemingly gave up after the first roadblock that seemed serious (but wasn't). Why didn't they try just a bit harder and overcome that roadblock? Because they didn't see standard-compliance as serious enough to warrant that little bit of extra effort. And nothing you say, Charles, will change this. Actions are louder than words. Yes, I believe you when you say that the team cares about standards-compliance, but the measure of just how much they care is in front of us: there is a way to do everything the team wants in straight C++, but the team overlooks it or doesn't care enough to use it. They care about standards-compliance, but they don't care enough about it to achieve it, even though achieving it is not actually all that difficult.

    And let's stop bringing up WRL. WRL is not fast and fluid. It is not a solution, it is a bandage.

  • Rockford NRockford N

    Garfield: "I predict 2-3 years from now MS will cheerfully announce they are done with C++/CX and offer the next iteration of the same."

    I fully agree. Actually, I suspect everybody here, including Charles himself, agrees with this, it is just that some people aren't afraid to say it how it is and others either try not to think about it or try to convince themselves that they really don't know what it's going to be like 5 years from now.

    What Microsoft does with C++ is a crime:

    [2002 or so, the era of Win32, Microsoft introduces .NET]
    Microsoft: hey, world, here is .NET.
    C++ folks: cool, we suppose we call it via HRUNTIME, CoCreateNetObject(HASSEMBLY, LPCWSTR) and so on, right?
    Microsoft: no, that's so 1990s, we have created a new language extension (ME F C++), use that.
    C++ folks: heh, a language extension? that's not standard-compliant, right? why not just use handles, Win32-style?
    Microsoft: it's all going to be fine, just listen to us, use the extension.
    C++ folks: ...ok.

    [2004, Microsoft adds a lot of stuff to .NET]
    Microsoft: yo, here is .NET 2, with generics and stuff, code away.
    C++ folks: nice, we didn't have a lot of fun with your language extension, but .NET 2 is cool, we'll look into it.
    Microsoft: ha, forgot to say, we decided managed extensions for C++ are no good, we are pulling them off.
    C++ folks: huh? does that mean we get handles and C-style functions?
    Microsoft: no, no, no, that's so 1990s, we have created a new language extension (C++/CLI), use that.
    C++ folks: but doesn't it worry you that the previous extension didn't quite work? could we just get handles, maybe? we'd like to be standard-compliant, if possible.
    Microsoft: nah, listen to us, everything is going to be fine, use the new extension.
    C++ folks: ...ok.

    [2011, Microsoft announces Windows 8 and WinRT]
    Microsoft: heya, heya, ladies and gentlemen, we are proud to present to you... WinRT!!! and the C++ renaissance!
    C++ folks: wow, WinRT and the C++ renaissance! cool! we suppose that's about the new C++ standard that just happened, right? very timely, Microsoft, well done!
    Microsoft: um... no, we aren't going to do much with respect to the new C++ standard.
    C++ folks: erm? so, what is this C++ renaissance thing about?
    Microsoft: it's about WinRT, the new native tech, you'll like it, we are sure!
    C++ folks: ok... do we use that via C++?
    Microsoft: nope.
    C++ folks: hmm... via C++/CLI?
    Microsoft: nope.
    C++ folks: then how?
    Microsoft: well, we have a new language extension! it's called C++/CX and it's about reference counting. ain't it great?!!
    C++ folks: ... (looking at each other in disbelief)

    True story.

    It is painfully clear that this can continue until cows come home. This is nuts, but this is how it goes. Does Microsoft care about standards? Yes. Will it trade standard compliance for more vendor-lock in, a prettier bell, a louder whistle, almost anything? YOU BET!

  • C64C64

    @Rockford N:

    I'm not afraid of say it how it is: when I needed to glue some C++ code with .NET (because e.g. I had to build a GUI in WinForms but needed to use some back-end existing C++ code), I was glad I had C++/CLI as a tool available to me to build the bridging layer from native ISO C++ to .NET world.

    If you don't like C++/CX extensions, you are free to not use them; WinRT can be programmed without C++ extensions using WRL; and if you don't like WRL, you are free to build your own native pure ISO C++ library for WinRT. If you succeed, you may make big money with that.

    Personally, I've a practical view of programming: if you give me tools and libraries written in pure ISO C++, which are easier to use and more productive than C++/CX, I would welcome them and use them. But as it is today, the best tool for the job seems to me C++/CX.

  • PFYBPFYB

    Good for you, C64.

    As for me and my team, after the news that VS 2011 will have basically no improvements for C++11 (vague promises of some improvements in this area in between VS 2011 and the next version are vague, we suspect these improvements consist of variadic templates and basically nothing else, which is too little and too late), after the disappointing flop of the "C++ renaissance" meme with WinRT and C++/CX, and after the disappointing lack of performance improvements in the developer preview of VS 2011, we decided we finally had enough and are not going to go with Microsoft any further. We are switching our development to the Intel's compiler.

  • PFYBPFYB

    And yes, if we decide to target WinRT (which is something we aren't yet sure about, it is not clear to us if this is worth doing at all, and the numerous restrictions on exactly how you have to program for WinRT don't help), we will do it via our own ISO C++ code, not via C++/CX. Why? Because we consider *this* more practical and more future-proof than using C++/CX.

  • C64C64

    @PFYB: Don't mix several things... If you speak of the lack of C++11 support and the not very good performance of VS201x IDE, I agree with you.

    But I think that these problems are not caused by VC++ Team; maybe the upper layers of Microsoft need to invest more money and more brainpower to increase C++11 support in MSVC (e.g. add new developers to VC++ Team).

    Regard the IDE being rewritten in WPF, this was not a very good move, IMHO. I'd have stayed with a native IDE, instead of spending time and resources in the .NET rewriting of the IDE (and put these resources for something different). Office has great performance, and its GUI is 100% native (and has the zoom bar capability, too Wink which was introduced in VS IDE with VS2010).

     

     

  • new2STLnew2STL xkcd.com

    @C64:

    >>maybe the upper layers of Microsoft need to invest more money and more brainpower to increase C++11 support in MSVC (e.g. add new developers to VC++ Team).

    Enter in the visualstudio.uservoice.com on 'Languages - C++'. There are some suggestions exact on this topic: "Speed up work on VC++: Suggestion 1: allocate more resources. ... Hire more people." (yea! 'moar' jobs! Angel )

    In regards of WPF, at least on my computer WPF only bad at cold start, but since VS2010 and the latest WinSDK you can use compiled XAML for native Ribbon and C++, it is how (sort-of) Office are done (also you can compile XAML in binary format for C# too), its verbose, but you can find a good amount of tutorials in the net and in the Chapter 10 of Hilo

    (I forgot to add a pinch of speculation, the new Windows Embedded Compact 7 have a 'better' support for compiled XAML with C++ binding Devil time for resurrect my old Axim)

  • GlenGlen

    @PFYB, as C64 says, try to stick with C++/CX here (though you are right about C++11 support of course) because you've got some great comments on C++/CX so don't let yourself get too distracted.

    Keep your C++/CX ideas coming.

    @Charles

    I'm not comparing a vm vs a native solution.

    Though I don't entirely know how much technology you are coupling in there as PFYB mentioned the possible scope of things.

    People have one code base. Not a native code base and a non-native code base unless it's one big compile to go back and forth. I am sure that is what you aim to do for your own code base when the time comes?

    I can't see a world where the average person maintains a native code base and a non native code base in any other fashion. Can you? If so, how?

    Therefore I don't see C++ as inherently native or not so the comparison is pointless to me at least. Is C# native or not native? Isn't that the same answer?

    You keep mentioning WRL, I don't see what that does for me other than increase the amount and complexity of Microsoft specific code I write. Even if it made my code more "standard".

    I'm not seeing value to do that. Can you explain?

    It doesn't help a ref class from having to manually delegate to an ISO class, does it?

    Having a ref class and an ISO class is putting two heads on a dog. You have to feed both wherever you go, that's where I want the complexity removed. There *has* to be a logical mapping between the two as you can do it manually, and I don't want to do it manually. What are your thoughts on this?

  • TomasTomas

    Charles wrote:
    > C++, on the other hand, has a very
    > different set of problems to solve if the goal
    > was to make WinRT transparent to ISO C++ users
    > (the C++ team did a LOT of work as well...).
    > It's hard to know if this is really possible
    > without too much added complexity at the
    > composition layer (the code you have to write).

    Charles you should read more carefuly what
    PFYB says in his comments. They make a lot of
    sense. This part is answered by his plea for
    extending the #import directive and writing
    codegen tool which would do the reverse thing.
    I remeber proposing extending #import myself
    under some of earlier channel9 videos.

    > Of course, there is a way for you to write ISO
    > C++ and not C++/CX to build native WinRTobjects
    > /components... We've already discussed this a
    > number of times: WRL. If you want to expose your
    > component to other components that aren't written
    > in the same language, then it's much easier to use
    > hats and refs than hand-rolling COM

    Again listen to PFYB and other C++ people who
    commented on using WRL (including me). It is
    absolutely not fluid and fast. I remember one
    channel9 video here where some indian guy
    introduced WRL and there was only one macro
    and one templated base class needed so it all
    looked fine and transparent. But it was only
    because he barely touched the subject! If you
    want to see how would look the real ISO C++
    WRL code look here:
    http://85.255.198.26/iangblog/2011/09/25/native-winrt-inheritance
    you can compare the code bloat in
    OnLaunched handler implementation using C++/CX
    and WRL. I am repeating myself now but this code
    looks worse than ancient MFC. So stop bringing
    WRL up as an alternative!

    We are not small babies. We like to watch the
    videos but we don't mindlessly consume everything
    what is told. We can build our opinions ourselves.
    And this long discussion is only consequence of
    that.

  • CharlesCharles Welcome Change



    We are not small babies. We like to watch the
    videos but we don't mindlessly consume everything
    what is told. We can build our opinions ourselves.
    And this long discussion is only consequence of
    that.

    Of course you're not... Nobody is suggesting otherwise. Please continue to speak your minds, share feedback and offer suggestions. It's always welcome here.

    C

  • CharlesCharles Welcome Change

    @Charles

    The Component IS the platform (any platform, not just WinRT) because the Component IS the library and the library IS the platform.



    I'm just saying that there are apples and oranges here, not just oranges.

    C

  • Quick analogy:

    There are std paper sizes and companies manufacturing printers operating on just on those std sizes - no company changes those standards. They just produce their products to be compatible with them so no matter which printer I buy/use I know that my standard paper size will work with this.

    What Microsoft does is - manufacturing printer (just for simplicity call it VS without mentioning all bolts and nuts like compiler etc.) and on top of that is reinventing new paper sizes (every few years) that, and here may I have your attention, is almost identical to the standard sizes but slightly "improved" in order to better serve MS clients. But MS being over all a business don't won't to constrain itself just to MS clients. They say that if you want to print standard sizes - well, no problem at all. Just take the part A11, A125, R58 and D12 and fit them in slots shown in a picture inside a manual attached with our printer and here you go, from now on you can print std sizes!

    And few years from now, there will be another paper size from MS. But not worry those who want print just standard paper sizes - MS will acomodate you appropriately.

  • DennisDennis

    @KMNY_a_ha: A very apt analogy!

    To continue it: ...and if you absolutely want to use standard-sized paper with the Microsoft printer, you can take a screwdriver, disassemble the printer, take the toner out and draw whatever you need to print on your paper by hand, here are the instructions how. That's WRL.

  • PFYBPFYB

    @C64, @Glen: I hear you on sticking to C++/CX. I will try not to get distracted, I promise.

    @Charles:

    I thought I would elaborate on one of the things that bothers me greatly about language extensions. That should partly explain why I am so vehemently against them.

    Every time you extend the language, you create semantic rifts which weren't there before. Take, for example, C++/CX and your 'ref new' syntax. Suppose you have a template function:

    template<typename T> void f(T* a) { T* b = new T(); ... }

    Can you use that function with a ref class? No, you can't. You can't do 'new T' with a ref class, you have to do 'ref new T'.

    Or, say, you have this function:

    template<typename T> void f(const T& a) { ... typeid(a) ... }

    Can you use that function with a ref class? No, you can't, ref types don't support C++ type info.

    Was it obvious to anyone that 'typeid' wouldn't work with ref types? It wasn't obvious to me, that's for sure. I mean, I can rationalize the behavior once I know what it is, but it isn't at all intuitive, and, frankly, the fact that 'typeid' doesn't work bothers me on its own (the above was a real function used for tracing).

    I can give you an example for C++/CLI, too, with C++/CLI you can have managed functions and unmanaged functions, but you can only have unmanaged lambdas. Managed lambdas are not supported. Was *this* obvious?

    There are plenty of places where your extensions break in non-obvious ways, and don't integrate well into the language. Plenty. And I am not even talking about much bigger semantic issues here, like the fact that we couldn't have circular references (they were memory leaks) in straight C++, then we could have them (and people did jump on this) in C++/CLI, and now we again can't have them in C++/CX (well, I personally am not going to use C++/CX, but those who will, especially those who were using C++/CLI before, will suffer). I understand that circular references are fair game in C++/CLI, but not in C++/CX, because the core technologies underlying these extensions are vastly different, but since these technologies are so different maybe you shouldn't have attempted to integrate them into the same language? Otherwise not only do you keep extending the language, you fluctuate between opposite directions! That's crazy, but that's what you are doing.

  • DennisDennis

    To PFYB - I couldn't agree more.

    When I heard of C++/CX I immediately thought "no, not again, give me C++, heck, give me plain old C, but stop bending the language to suit your strange, temporary needs". All my code is Windows-only, I don't care about platform independence one bit, but what you are doing with the language is a gross offense.

    Please listen to PFYB. The things you are adding to the language end up not well integrated with it. C++ is already hard, but your extensions turn it into an absolute mess. You partially destroy the internal logic of the language.

    In addition to the angle explored by new features not integrating well with the rest of the language, there is also an issue of things like properties, delegates and generics. Oh god. Please forgive my sarcasm, but I wonder, when you decide to extend C++ with a particular feature, does it not occur to you that maybe you are not the only one who thought of adding that feature to C++? Maybe that feature was considered by the C++ committee or the C++ community, and they rejected it - at least in the form you are about to add it - as non-suitable? Or maybe the language already has means to do what you want and the feature you are about to add was considered to bring too little to the table and was rejected on that basis? Or maybe the feature is not in the language because there is a replacement feature coming in some future version of the standard? What's up with C++/CX extending the language with features I mention above? You are adding them to C++ like it is your own language. Are you not aware of seemingly endless debates regarding, for example, properties on the C++ forums? Do you not realize that not all people WANT to have properties? Is it really your role to pick and choose what C++ will and will not have, which direction it will go? What arrogance!

    Stop with the extensions, give us libraries.

  • C64C64

    I thought I would elaborate on one of the things that bothers me greatly about language extensions. That should partly explain why I am so vehemently against them.

    Every time you extend the language, you create semantic rifts which weren't there before. Take, for example, C++/CX and your 'ref new' syntax. Suppose you have a template function:

    template<typename T> void f(T* a) { T* b = new T(); ... }

    Can you use that function with a ref class? No, you can't. You can't do 'new T' with a ref class, you have to do 'ref new T'.

    Or, say, you have this function:

    template<typename T> void f(const T& a) { ... typeid(a) ... }

    Can you use that function with a ref class? No, you can't, ref types don't support C++ type info.

    @PFYB: you are having a good point on this, thanks.

    However, note that it is possible to integrate ref classes with STL containers, e.g. it is possible to have std::vector<SomeCxClass ^>.

    I wonder if they could refine the extensions to reduce the "impedance" with the rest of the C++ language.

     

  • new2STLnew2STL xkcd.com

    @C64

    >>I wonder if they could refine the extensions to reduce the "impedance" with the rest of the C++ language.

    For this point I have to disagree, the "impedance" (lets call it pervasibility) in this case is what can prevent from the border/adapter/wrapper code to invade your existent code. CX as less pervasible can force you to be doutrined and write proper wrappers while WRL as more pervasible can let you "mix" code where it is necessary (or for achieve source code compiler portability). But you cant blame the extensions for the poor choses of the programmer in doing wrong stuff (here we have a word for this, it is called "gambiarra" Wink )

  • PFYBPFYB

    @C64: Oh, you liked it? There is lots more. For example:

    1. We can have an array of smart pointers. Can we have an array of hat pointers? Nope, 'T^ a[3];' is a compile error. We can have a regular pointer to a hat pointer (T^* a;) and this works fine, but we can't have an array of hat pointers. Why? Your guess is as good as mine.

    2. With C++ types, we can stack stars to construct pointers to pointers, pointers to pointers to pointers, etc. Can we do this with hats? No, 'T^^ a;' is a compile error. Yes, stacking stars and hats is useful.

    3. It is fairly common for a C++ class to derive from a template class. C++/CX has generics. What happens if we try to derive a C++ class from a generic interface class? Oops, that's a compile error, too. (Example: 'class C : public I<int> { ... };'. This compiles if I is a template interface: 'template<typename T> class I', but doesn't compile if I is a generic interface: 'generic<typename T> interface class'.)

    4. A C++ template can, of course, take another template as a type parameter. Can a generic take another generic as a type parameter? No. Can a template take a generic as a type parameter? Yes. Can a generic take a template as a type parameter? No.

    5. We can use instances of ref classes through hat pointers (T^ p = ref new T; p->x = 2;) or we can pretend they are allocated on stack (T p; p.x = 2;). Good. We can take an address of a hat pointer (T^ p = ref new T; f(&p); ... with f, for example, at some point doing *p = nullptr;). Can we take an address of an instance of a ref class that pretends it is allocated on stack? Nope, this is a compile error.

    6. If we take a hat pointer as an argument, we can prevent changes to the underlying ref class by switching the type of the argument from hat to const hat (T^ -> const T^). Good. This prevents direct writes. Can we now mark methods in T which do not change its internal state as const (ref class T { void f() const {} };) and leave methods that change its internal state as non-const? Nope, marking methods of a ref class as const is a compile error.

    7. Ref classes can have automatic properties (ref class T { property int x; }). Ref classes can also have unions or structs that contain unions, like VARIANTs. Good. Can we have a union with, say, a float and an int and declare one or both these things as an automatic property? Noooooo, this is a compile error.

    8. What about operator overloading, can ref classes overload operators (think about constructs like matrices)? Why, yes, they can. But if you think this works in the way this worked in regular C++, think again. Your overload prototype likely uses const references (const T& operator+(const T& r) { ... }). Well, this doesn't work with a ref class, since there is no such thing as 'const T&' for ref classes. You might try using plain types (T operator+(T r) { ... }). Well, this doesn't work either, since attempting to return '*this' fails, ref classes do not have a copy constructor. What you can do is use hats (T^ operator+(const T&r) { ... }), but this effectively leaves you with an implementation for +=, using + modifies one of the arguments.

    And this is just scratching the surface. The above took me a total of about 45 minutes to compose - make a quick list of things to try, try them one by one, write down the results. Just in case you are interested, the original list contained 12 items, 8 items exposed problems as above, 3 items worked, the remaining item needs further investigation (having two identically named ref classes in two different compilation modules makes the debugger use only one definition, it can be that the debugger contains a bug and doesn't know that identically named ref classes in different compilation modules are not the same, or having identically named ref classes that are different is actually not allowed - which, of course, would be vastly different from C++).

    By the way, how does C++/CX interoperate with the previous extension, C++/CLI? Can we have managed code, unmanaged code and WinRT code in the same file? C++/CLI had #pragma managed / unmanaged, so we should be fine, right? No, of course this doesn't work.

    A total mess.

  • @PFYB and others - I'm sure there is only one person who can answer competently to all those "why" questions. Mr herb sutter - "the" C++ architect at MS.

     

  • new2STLnew2STL xkcd.com

    @KMNY_a_ha: He has already answered in Using Windows Runtime from C++ (plus other vídeos and blogs from VS team, but it seems that was not enough to appease the angry-ones ...)

    @PFYB : add to your tests the operator %, it retrieve a handler '^'

    ref class MyClass;

    MyClass m;
    auto x = %m; //x is of type MyClass ^

    //now you can do like "Under the Covers of WinRT Using C++"
    //and extract the vtable pointer
    auto vtable_array = (ptrdiff_t *)&x;

    //auto x = (ptrdiff_t *)&%m is invalid cause '&' needs an lvalue

    >>A total mess.

    Only because the compiler not let you do wrong stuff?

  • PFYBPFYB

    @new2STL:

    "He has already answered in Using Windows Runtime from C++ (plus other vídeos and blogs from VS team, but it seems that was not enough to appease the angry-ones ...)"

    You know, new2STL, I think I have read and heard more or less everything said on the matter by Herb Sutter. I don't remember him providing satisfactory answers to any questions. He did make a vague promise on adding some unspecified features of C++11 *after* the version of VS that is currently not even in the beta, but probably before the next one, and that's it.

    Did Herb Sutter at some point explain why the team went with C++/CX and didn't use ISO C++? If he did that and I missed it, please point me to that explanation.

    "A total mess." -- "Only because the compiler not let you do wrong stuff?"

    So, if I understand you correctly, you say that, for example, 'T^ a[3];' does not compile, because it is "wrong stuff"?

    What criteria do you use to distinguish "wrong stuff" from "right stuff"? I surely hope it is something more than simply what the implementation does.

  • @new2stl where (which video file, what time on this video) herb sutter answered to those questions? Would you mind pointing me to them? I'm asking you because I've watched it at least twice each of them and I cannot recall any of those answers being given. So could you kindly, point me out there?

    Thanks

  • new2STLnew2STL xkcd.com

    @PFYB:: I'll put it clearly and sincere. Herb Sutter, Jim Springfield, Diego, Stephan, Charles, C64, me, and others already answered but you insist in blinded-hate ignoring any start of dialog throwing again and again the same pre-assumptions and misconcepts about the purpose of the language extension. Ignoring its scope, its purpose, its runtime-OS relation and mainly ignoring you can use WRL templates, wrapper classes and macros if you really hate CX.

    Jump on any conversation about CX with walls of (rage)text not respecting who want learn and understand more of how it works and how to work with it. For me, my personal impression this is like acting like an internet troll. It is impossible to any of already cited persons deep any conversation cause this posture of bash-demoralize first, ignore later show then you not interested (you will see this posture of not continue a conversation on any teacher or engineer/programmer leader). Why you not make like your nick name and "please fix your bugs" constructivly?

    Let can you (in a general sense) respect who are interested in the CX and write your angry in a forum thread?

    About the arrays, who can answer this question if, again, you posts show you are not interested in know the why? If you read the answers Stephan and Jim tried to initiate a conversation but you promptly bashed a wall of rage. I want know the deeps for this question too but your attitude is driving them away. What I can presume is cause arrays are a pointer for a chunk of memory and giving this access to the programmer can lead to a corruption of the handlers (managed by the COM apartment), also the scope of CX are the border (yea, you hated word) and its not good/safe/good practice have pointers cross boundaries, so if you want an array, use Stephan's WFC::IVector (?). Because it is a compiler keyword wich meaning is not direct a type but a context relative series of procedures (?) "But but, I will use array only internal to my code" even in this case, its safe to stay on IVector, who knows when something will go crash and leak and let lots of winrt objects orphans (!?) Expressionless. But serious now, this response can lead to another full length GoingDeep, but why spend hours of labor recording it if people (like you) will throw it in the mud. Change your attitude pls Wink

    Sorry Charles for the explosive text, but I have to put it out. From now I'll no more answering to PFYB.

     

  • new2STLnew2STL xkcd.com

    @KMNY_a_ha: First you can see any of the Build2011 videos related to WinRT, second you can see the blog post of Jim. I can understand a person dislike extensions with passion, but if you can't control you rage and put questions in proper way to build a dialog you will never got the answers Sad (I know you agree with PFYB, "knowing me knowing you, a-ha")

  • PFYBPFYB

    @new2STL:

    You don't like what I am saying, fine. I agree my tone is not the most friendly. Please keep in mind me and my team (and a lot of other people here) have been asking Microsoft not to dilute C++ with extensions, etc, for a long, long, looooooong time, to no avail.

    You want the discussion to be constructive, good, I want the same. Let's stick to the facts.

    Do the above examples I provide show that C++/CX does not integrate well into the language? Do they or do not they?

  • @new2stl and I've said already that I've watched all of them at least twice and in none of them answers to those questions are given. Second, Jim in his blog also doesn't give answers to them.

    As for rage? Where on this or Jim's thread I "raged". I've asked you politely to point me to the specific time on a specific video which would demonstrate that what you're saying has any back up. But you, just in the style of guys from MS conveniently telling me to see those videos, again... even though I've just explained to you that I saw them at least twice, yet you do not answer what you've been asked. Just like they don't.

    And as for deciphering "KMNY_a_ha"? Your point is? It's not like I've tried to conceal the fact that "KMNY_a_ha" and "Knowing me knowing you, a-ha" is same personr. I've explained that to Diegum long time ago that both nicknames are mine and the KMNY_a_ha is due to the fact that I cannot register myself with my original nickname on Channel9. So your point is, what? Sherlock?

    So are you going to show in which video/blog herb sutter answers to those questions mentioned here, or you just going to simply state that those questions had been already answered?

  • C64C64

    , new2STL wrote

    @PFYB:: I'll put it clearly and sincere. Herb Sutter, Jim Springfield, Diego, Stephan, Charles, C64, me, and others already answered but you insist in blinded-hate ignoring any start of dialog throwing again and again the same pre-assumptions and misconcepts about the purpose of the language extension. Ignoring its scope, its purpose, its runtime-OS relation and mainly ignoring you can use WRL templates, wrapper classes and macros if you really hate CX.

    I don't know of other threads, but in this thread it seems to me that PFYB is having some good points and is giving constructive feedback. I differ with him on some points, but I see no "hate" in his words... I just see a technically interesting conversation.

     

  • Bartosz BieleckiBartosz Bielecki

    @C64 You mentioned that one cannot pass smart pointers between modules. I keep wondering, why is that not possible, if both new smart pointers (shared and unique) posses a deleter? I assume, that thanks to this OUR module will deallocate the resource, NOT theirs.

  • CharlesCharles Welcome Change

    , C64 wrote

    *snip*

    I don't know of other threads, but in this thread it seems to me that PFYB is having some good points and is giving constructive feedback. I differ with him on some points, but I see no "hate" in his words... I just see a technically interesting conversation.

    I agree. The tone here is not hateful at all (that's happened on other threads and not by PFYB, mind you, but not here - it's been quite civil. Thank you!). What I see here is frustration and perhaps some misunderstanding, too.

    I do respect new2STL's desire to keep the tone respectful and constructive here. Thanks for that reminder, new2STL! 

    It must be that the information you seek hasn't been supplied in this episode of GoingNative and  in all of the BUILD videos on C++/CX. Right? Is this the case? Deon Brewis' great BUILD session discusses the goals (and internals of C++/CX - from compiler output to the reasoning behind the new model), right? Did you watch that one? What about Jim Springfield's VC blog post on the C++/CX design? I know you've read that one, PFYB since you've commented there. Looks like we need to provide more information.

    What I'm hearing from you is that you need more information and justification.

    C

     

  • C64C64

     Bartosz Bielecki wrote:

    @C64 You mentioned that one cannot pass smart pointers between modules. I keep wondering, why is that not possible, if both new smart pointers (shared and unique) posses a deleter? I assume, that thanks to this OUR module will deallocate the resource, NOT theirs.

    You can pass C++ smart pointers across module boundaries, but it is very constraining, as with other C++ classes.

    I've not tried myself, but you may want to try to pass a VC9 (VS2008 SP1)'s shared_ptr across module boundaries with a module built with VC10 (VS2010)...If the layout and implementation of shared_ptr of these two different compilers differ, you have crash and burn. But you can safely use COM components written with VCx with clients written with VCy

  • Charles asked if I'd pop in for a quick comment to answer "why have C++ language extensions for WinRT?"

    Short answer: You should still write nearly all your code using portable ISO C++ only. There's going to be some Windows-specific code if you want to use some Windows services (e.g., Metro), just as there's going to be some CORBA-specific code if you want to use CORBA services, and C++/CX actually exists to reduce the amount of nonportable Windows-specific code you have to write, although we also support WRL as the more traditional "ATL+MIDL+..." style approach we've all historically used for COM and CORBA.

    Longer answer follows:

    1. WinRT is an evolution of the COM/CORBA model.

    Native C++ types aren't ABI-safe, programming language-neutral, version-safe, or otherwise capable of meeting the multi-language and serviceability design constraints of WinRT. Historically when such capabilities have been needed, we're resorted to some non-portable solution like COM or CORBA which rely on compiler extensions + libraries + build/tool extensions.

    WinRT is just an evolution of COM. Supporting COM or CORBA has always required extensions beyond just ISO C++, from language/compiler extensions (e.g,. #import is not ISO C++), to custom libraries (e.g., ATL), to build/tool support (e.g., IDL/MIDL). WinRT adds extra wrinkles on top of COM, such as inheritance implemented under the covers using COM aggregation, and so supporting it requires a bit more work than old-style COM, but that's just a matter of degree; the problem is exactly the same in kind.

    Note that we are also providing WRL, which can be considered an evolution of the ATL + tools like MIDL approach. If you prefer that, go ahead and use it; your code will look more like you're using just a library, though I will point out that you'll be using lots of non-ISO C++ scaffolding just as with COM or CORBA.

    You can use C++/CX or WRL. I would just ask that you try both, and even if you choose WRL you'll be able to see why the C++/CX option is designed to make it a lot easier -- and actually less invasive in your code -- to write the non-ISO C++ thin wrapper parts of the code because we've employed the compiler to help you by avoiding build/tool complexity (e.g., no MIDL/IDL compilers or files), better language integration (e.g., you get to use exceptions naturally across module boundaries), and other simplifications which will actually reduce the amount of Windows-specific code you'll write.

    2. WinRT is a foreign (non-C++) object model almost as much so as .NET.

    Many (but not all) of the answers to "why do we need C++/CX language extensions for WinRT?" are the same as the answers to "why did we need C++/CLI language extensions for .NET?" which I wrote up in A Design Rationale for C++/CLI.

    What's the same: Nearly everything. Most of the same design constraints apply -- we are binding to a non-C++ object model that supports multiple client languages, metadata, ABI safety, and so forth. Even some basic abstractions that look the same have different semantics (e.g., classes may use single inheritance only), there are additional non-C++ abstractions that need to be authored and consumed (e.g., properties, delegates, events), and the environment requires extra non-C++ knowledge and manipulation (e.g., to consume and generate metadata). As such, binding to a foreign object model requires additional compiler knowledge to account for the differences -- and anything that requires compiler knowledge can't be written as just a library. Note: Even if a library-like syntax were chosen, it would simply be a language feature dressed in library clothing.

    Now, WinRT is an enhanced COM, and as such is closer to C++ than .NET is. So a few constraints don't apply and so C++/CX is slightly simpler that C++/CLI. The main relaxed constraint is that in WinRT we don't have to worry about a compacting GC, so objects' addresses do not change. For that reason, we can (and do) easily allow "mixed types," meaning a ref class with data members of native C++ type data members and vice versa (see 3.1.3.3 in the Rationale linked above; we never got to this for C++/CLI but do support it for WinRT and without having to have two separately allocated subobjects), and we have less need of some helper abstractions like pin_ptr and interior_ptr that matter a lot more when binding to foreign object model and runtime that permit compacting GC.

    3. Neither C++/CX nor WinRT is recommended most of the time.

    This can't be said enough: C++/CX and WRL are special-purpose tools, not replacements for portable ISO C++. The guidance is the same for all the Microsoft-supported languages that are WinRT-enabled: You should continue to write nearly all your code in your normal language (in this case portable ISO C++; for .NET programmers, C#; for web programmers, Javascript) and use WinRT only on the boundary where you want the cross-language, ABI-safe, etc. environment. Just like COM or CORBA. Because WinRT is COM.

  • STLSTL

    C64> I've not tried myself, but you may want to try to pass a VC9 (VS2008 SP1)'s shared_ptr across module boundaries with a module built with VC10 (VS2010)...If the layout and implementation of shared_ptr of these two different compilers differ, you have crash and burn.

    The STL never has and never will guarantee binary compatibility between different major versions. We're enforcing this with linker errors when mixing object files/static libraries compiled with different major versions that are both VC10+, but for DLLs and/or VC9-and-earlier, you're on your own when it comes to following the rules.

  • PFYBPFYB

    I am sure this again will be interpreted by new2STL as me not intending to listen, but...

    @hsutter:

    Please excuse me for asking this, but did you read the thread? We know that WinRT is an evolution of COM, we get that WinRT is a foreign object model, and we heard that we are supposed to use C++/CX "only at the border" for what seems a hundred times already. We also heard about WRL. We are asking about something else.

    The main question raised in the thread is:

    ***
    Why, instead of doing C++/CX, did you not use a design that requires no language extensions, eg, by generating C++ wrapper code for consuming WinRT components (similarly to #import) and generating C++ wrapper code for exposing WinRT components (the reverse of #import)?
    ***

    Before you say so, yes, #import is not part of the standard, we can talk about why we think #import is fine while other language extensions aren't.

    Your post simply reiterates the same general points we have already heard a number of times, and, as such, does not answer the above question.

    Specifically:

    "Native C++ types aren't ABI-safe, programming language-neutral, version-safe, or otherwise capable of meeting the multi-language and serviceability design constraints of WinRT." -- We know this. Wrapping code both ways allows meeting the requirements of the ABI without altering the language.

    "Note that we are also providing WRL, which can be considered an evolution of the ATL + tools like MIDL approach." -- Using WRL is not fast and fluid. Saying 'just use WRL' is almost like saying 'just use a hex editor'. If using WRL was as fast and fluid as using C++/CX, or as fast as fluid as using WinRT from C#, we likely wouldn't have this thread.

    "... you'll be able to see why the C++/CX option ... will actually reduce the amount of Windows-specific code you'll write." -- The question is, again, why did you not allow writing Windows-specific code with equal ease in ISO C++. We get that C++/CX is expressive and not very verbose. We think you could have achieved the same or better with ISO C++.

    "Most of the same design constraints apply [as for C++/CLI] -- we are binding to a non-C++ object model that supports multiple client languages, metadata, ABI safety, and so forth." -- See above. Wrapping code both ways allows meeting the requirements of the ABI without altering the language. We agree metadata is great, please continue generating and using it.

    "Even some basic abstractions that look the same have different semantics (e.g., classes may use single inheritance only), there are additional non-C++ abstractions that need to be authored and consumed (e.g., properties, delegates, events), and the environment requires extra non-C++ knowledge and manipulation (e.g., to consume and generate metadata)." -- See above and see the posts in the thread. Wrapping code both ways allows all this while staying withing the boundaries of the standard.

    "As such, binding to a foreign object model requires additional compiler knowledge to account for the differences -- and anything that requires compiler knowledge can't be written as just a library." -- Yes, binding to a foreign object model requires additional compiler knowledge, and, yes, anything that requires additional compiler knowledge can't be written as just a library. But using a language extension is not the only way to apply additional compiler knowledge. You can, for example, as suggested above, use additional compiler knowledge to generate C++ wrapper code. There are other ways to apply additional compiler knowledge as well.

    "Now, WinRT is an enhanced COM, and as such is closer to C++ than .NET is. So a few constraints don't apply and so C++/CX is slightly simpler that C++/CLI." -- Good, but, first, the question was not about this, and, second, even though WinRT is, as you say, closer to C++ than .NET ever was, and C++/CX had less hoops to jump than C++/CLI ever had, this, sadly, didn't allow you to integrate C++/CX into the C++ much better than C++/CLI. If you read the thread, you will find a post with examples of language problems that C++/CX has. The general feeling from using C++/CX is that the number of such problems is not less than that for C++/CLI. While reading that post please note how using standard C++ constructs instead of C++/CX constructs (eg, smart pointers vs hat pointers) easily avoids the problems. This is one of the reasons we are asking why you didn't do everything in ISO C++.

    "You should continue to write nearly all your code in your normal language (in this case portable ISO C++; for .NET programmers, C#; for web programmers, Javascript) and use WinRT only on the boundary where you want the cross-language, ABI-safe, etc. environment." -- We've heard this many times already, there is no need to repeat. What you are saying implies that the border is a small thing, and is easily separable from the rest of the application. Me and many others disagree. In most projects I have worked in there were multiple borders and most of the code was touching these borders in some way. You are asking us to add one more border. This is a considerable expense. From experience, this new border will end up touching a lot of code. Also from experience, concepts from this new border *WILL* leak into other parts of code, for performance reasons, because someone didn't know any better, or because someone was in a hurry to fix a bug. By tying WinRT to a new type of border you are putting us and other C++ developers into a position where we have to choose between using WinRT and living with the consequences of the new border (reaping the benefits of C++/CX, but also incurring heavy costs), or writing our own wrappers for WinRT, or maybe not using WinRT at all. WRL is a non-option, it does so little that using WRL is equivalent to writing our own wrappers. Saying that something should only be used 'just on the border' isn't saying much. Plus, getting back to the topic of the thread, the central question is not where we should be using C++/CX. We heard you on that already. The central question is why we should use C++/CX and why you didn't do everything in C++.

    In sum, Herb, I appreciate your posting here, but could you please read the thread and do another posting addressing the actual issues discussed here.

    Thank you.

  • WarrenWarren

    I second PFYB. Thanks so much for the detailed and thoughtful post!

    Charles, thanks a lot for bringing up Herb Sutter, this is much appreciated, but, Herb, could you please read the thread and post on the specific issues raised? Thank you.

    One more word on borders. The application I am currently working on uses a modern, modular structure. We have a separate data access layer into which we can plug in different data providers. We have a separate presentation layer which we connect to the desktop interface and the web interface (web is actually several interfaces). What you would normally call business logic, of course, is also a separate layer. Do you know what we are working on most of the time? The interface layer and the ties between that layer and everything else. If WinRT was not about the UI (plus so many different other things), if it was more on the level of, for example, OLE DB, I would be more sympathetic to the argument that using C++/CX to access WinRT is no big deal. As it stands, however, the main and most compelling reason to use WinRT is to use the new Metro UI, and I just know that the border at the level of the UI is huge.

  • GlenGlen

    @new2STL, like C64, I support PFYB in that he been very constructive in this thread thus far and I certainly share the principles he is promoting.

    I will post again later when I have more time but in short I do no share Herb's views on this but I will elaborate soon.

  • @PFYB: That is very well summed up - you are really hitting the point here.

    @Warren: You are absolutely correct. This is one of my big concerns too.

  • C64C64

    , STL wrote

    C64> I've not tried myself, but you may want to try to pass a VC9 (VS2008 SP1)'s shared_ptr across module boundaries with a module built with VC10 (VS2010)...If the layout and implementation of shared_ptr of these two different compilers differ, you have crash and burn.

    The STL never has and never will guarantee binary compatibility between different major versions. 

    STL: Thanks for the confirmation.

     

  • @PFYB my suggestion to you, could you please list those questions, bold them out Wink and number them so there will be no wriggling out/avoiding/omitting excuse anymore as to which and what specific questions has been asked. Then in reply mr herb could also number his answers appropriately and this would (I think) greatly simplified whole communication "thing".

  • CharlesCharles Welcome Change

    @KMNY_a_ha: Well, this is the question, right? ->

    Why, instead of doing C++/CX, did you not use a design that requires no language extensions, eg, by generating C++ wrapper code for consuming WinRT components (similarly to #import) and generating C++ wrapper code for exposing WinRT components (the reverse of #import)?


    C

  • @Hi Charles, thanks for reply.

    The question/s is/are (depends on how you read it, as a one question with branches or few separate questions said it in one breath):

    Could that (the goal of C++/CX) be achieved without modifying syntax and semantics of C++,

    if no, why? What is it in CX that couldn't be done using existing language futures + compiler's help + other (if necessary) tools help?

    if yes, why did Microsoft do that?

    I would really appreciate if you could ask mr sutter and if he would be so kind and reply to them, with  presenting examples and counter examples of code that clearly show that what you did with CX was the only and best way to go and it could not be done with C++.

    Thank you.

    P.S.

    If you could wait couple of days till other people get the chance and ask their questions, and then if you could compile them into one post, post this compilation with numbered questions here on this thread and then forward it to mr sutter get his numbered replies and post them here would be really appreciated.

    C++ Rules and Rocks!

     

  • GarfieldGarfield

    @PFYB: great observations.

    Ironically, MS extensions are restrictions. They extend the language with constructs nobody wants, at the same time restricting it where everybody wants. They are also viral. Once put in some places they severely restrict what you can do with that code and that tend to propagate from that boundary and require efforts to prevent the bleeding via probably the same firewalls of raw pointers and built-in types that MS considers so 1990.

  • CharlesCharles Welcome Change

    Didn't Jim Springfield explain the #import (for consumption) problem in his post on the VC blog (authoring complexity)?

    The #import feature that was available in VC6 provides a good mechanism for consuming COM objects that have a type library. We thought about providing something similar for the Windows Runtime (which uses a new .winmd file), but while that could provide a good consumption experience, it does nothing for authoring. Given that Windows is moving to a model where many things are asynchronous, authoring of callbacks is very important and there aren't many consumption scenarios that wouldn't include at least some authoring. Also, authoring is very important for writing UI applications as each page and user-defined control is a class derived from an existing Runtime class.

    C

  • CharlesCharles Welcome Change

    @KMNY_a_ha: We do need to be respectful of Herb's time and ensure the questions presented are clear and have not already been answered (like the #import question, which Jim Springfield seemingly answered already, right?).

    C

  • TomasTomas

    Charles that question was only *partly* answered by Jim.

    As PFYB says it's needed to generate code wrappers in both ways. One way is through the #import directive which allows you to *consume* WinRT interfaces through ISO C++ wrappers. So you will get set of automatically generated C++ classes with inheritance and exceptions and you can easily use them in the C++ way. There is no need for Platform::String etc. because wrappers accept standard C++ types like std::wstring and transform it to ABI safe structures before they call WinRT raw interfaces. The implementation for derived members calls QueryInterface. Exceptions are thrown when HRESULT calls fail. Most of this functionality is already implemented for a long time (Jim says since VC6). It only needs to be updated to understand the new metadata format (.winmd) and new concepts (COM inheritance). This would be the true WinRT projection to C++. Jim and others indirectly conclude that this would be possible.

    Opposite way is also needed. Developer writes ISO C++ class and wants to expose it to other language or wants to handle events. Jim is calling this *authoring*. So in short you have to write tool which parses the C++ code and generates wrapping COM interfaces for classes that are marked for export (By __declspec or by using base class with special name). The wrapper implementation catches all exceptions and transforms them to bad HRESULTs. Exposes WinRT interfaces with ABI safe types. And also generates metadata.

    Now this approach has many advantages
    - uses only ISO C++. Very easy to use. All COM-related code is automatically generated/hidden. No CX extensions, no Platform::Strings
    - If the functionality is implemented in separate tools one can use older VS compilers or even third party compilers
    - It seems that it would be easier to implement this than whole C++/CX thing

    So we would like to hear what are the problems with this approach and why it was not preffered over CX extensions. I hope my english is clear enough here.

  • GlenGlen

    @Everyone:

    It's not about *no* language extensions, it's about the *right*, *necessary*, and *justified* ones. *Right* means I would support even *more* extensions if they could be *justified* and were correct, or *none* if they weren't.

    I hope this dialogue means Microsoft is equally open to this. To that end I hope Microsoft (at least Herb) is making notes, as people (at least me) will ask for them later as evidence.

    My own opinion is this: it could be that MORE extensions may be necessary beyond what MS has proprosed, but if we can show that NO or less extensions are needed, then that's even better iff it achieves the same and right goals. But either is fine, if it is right.

    In any event, the bar has to be high. MS needs to be challenged to be sure its right and more so when MS doesn't have a history of getting it right enough. COM was half baked, and .NET is half performant. C++/CX is what COM should have been, but it is a day late and still a dollar short as I hope to explain. It needs to be not just good for MS, but good for C++ and its customers.

    I agree with the "lost decade" people have commented about as Microsoft has persued this and got itself tangled up all the time.

    @Herb / Microsoft. Here's are my concerns:

    1. Why is a "Foreign Object Model" that is SO foreign to C++ that it causes so much problems justified? We can't afford more lost decades.

    2. Is this because MS needs to support its legacy COM code and .NET? If so, I'm not sure that's reason enough for C++ to suffer or MS to keep persuing thing this this way. If MS didn't have a legacy, would C++/CX be the solution? Wouldn't the evolution of a module based C++ have been this deal?

    3. C++/CX does a lot for COM, but I'm not sure it does enough for C++. It creates two different but equivalent concepts in C++ that will have to talk to each other - as Herb says himself. This is rarely a good idea. C# does not have this issue. It does not have two equivalent concepts of class surfaced in the language. Why is this good for C++? I do not believe C# is tied to Windows, so does C++ need a type that is? A ref class is a logical competitor to a C++ class.

    4. C++/CX provides insufficient means to navigate between an ISO class and a COM class, when they surely have to - Herb made the case himself. This is a key statement: this can and must be nearly transparent for this thing to fly even if one were to agree the other key issue that C++/CX and COM was neccessary at all (and thats not agreed yet either). What justification is there that it cannot be transparent? Is it good enough justification? If it can't be transparent, shouldn't ref class go? Anything that leaves C++ with a significant wrapping burden of virtually any kind at this level is bad for C++. C# doesn't cause this. Why should C++?

    I believe MORE language extensions might be the answer here and some of them could be standard. As an Adapter of some kind? This could go in the language and not in the compiler/tool that does the adaptation. This makes it useful elsewhere and on other platforms. Should other platforms have C++/HP/IBM? Why not one solution for all? Smarter people than me, please test this idea, I don't claim to have had time to think it through but fleshing the idea out together is what the ISO team does, and that's us. BUT:

    5. If/is ISO C++ so broken that it needs a whole new object concept? If so, shouldn't we fix it? Clearly the dialogue of opinions suggests yes. If COM is that fix, wont that be the future? If so, great, lets standardize it. If C++ isn't broken enough that it needs a new object concept, how can Microsoft justify it needs it? In either case, class and ref class are equivlant concepts and standard or not they need to connect more seemlessly; ideally, transparently. The Adapter was one rough idea to bring/map the two together, but ideas are needed, ISO or otherwise, to make the friction of two class concepts less, regardless if they come about in either standard or non standard form.

    6. MS is clearly (probably with some informal WG21 team blessing? Everyone?) creating a language within a language (again) - by creating yet more notions of a class. If that allows MS to "innovate" in their own sub language and keeps MS from messing with the core language so both can evolve freely and independently, that *might* be something. But would it? C++/CLI never acheived that goal, and here we are with COM/C++/CX doing it again. Is it worth it? and can the risk or effort be reduced beyond what is currently proposed to allow it?

    If WG21 informally agrees to a language within a language, maybe they need to sell this too or have the co-existance better planned? Bjarne Kanobi, you are our only hope?!

    In summary:

    The goal of Componentisation (C++/CX) is good.
    C++ has a concept of it.
    More is needed of it.
    Interopability is good, without it C++ and Componentisation is missing a market.
    C++ needs to be better at it.

    BUT:

    We can't allow MS to make the Component the next Platform battle field.
    C++/CX is not A library, it is The Definition of Library.
    Standard C++ cannot afford to give up the concept of Component to Microsoft, or it will be at odds with itself.
    Introducing two classes that aren't seemless is the start of that.

    So: @Charles for Herb.

    1. The case for COM (C++/CX) has to be made. Is it made?
    2. If the case for COM is made, shouldn't it be standard?
    3. If the case can't be made or made standard, should MS be using it, or forcing it on the rest of us? Why is that good for us? Says who?
    4. Either way, aren't a class and a ref class equivalent (no, not the same)?
    5. Aren't class and ref class competitive?
    6. If either triumphs, they have to talk to each other still (or its an agenda) and one is work for the other.
    7. That is a concern and it will grow. Why can't or shouldn't the connection between class and ref class be made transparent?
    8. If it can't be transparent? Is this worth it or the right solution?
    9. Have we made our case to Microsoft? If so, why so? If not, why not? What's the plan?
    10. Thanks.

  • PFYBPFYB

    Many good posts.

    @Charles:

    One thing that I want to make clear:

    "... (like the #import question, which Jim Springfield seemingly answered already, right?)"

    No. See the post from Tomas. Very shortly, Jim is saying that the problem has two parts (consuming and authoring) and that #import solves only one part (consuming). We agree that #import solves only one part, but point out that a feature similar to #import - generating code that is facing out of C++, instead of into it - solves the second part. Later in the thread on vcblog, Jim seems to acknowledge that the proposed approach is possible and would work.

    The questions thus are:

    Why wasn't it done this way? What aspect of C++/CX can not be done using ISO C++, generating the code both ways as proposed?

    Hope this makes it clear.

  • @Charles, Hi, I'm sure lads from C++ community will do their best to formulate them as clearly and succinctly as possible.

    Regards

  • grumpygrumpy

    Ok, simple, concise questions for the Microsoft team:

    1: Do you have any actual experience with the whole "only use C++/CX at the boundary" thing? Are Microsoft's WinRT components written in this way? Or did you just go all-out C++/CX for those because "it wasn't important", and then made sure that *in theory* it is possible to restrict C++/CX to the boundary?

    2: Was an approach as discussed by PFYB and apparently discussed with Jim Springfield on the VCBlog considered? Could it be considered for a future release?

    3: What about a "Friendly WRL"? WRL gives full access to the WinRT plumbing, and the ability to do things that C++/CX can't do. But for the most part, we don't need that. Most likely, we don't even need all that C++/CX does. So, could a smaller, simpler, cleaner, more user-friendly library be developed which, instead of doing everything WRL does, tries to do *roughly* all that C++/CX does? Cutting a few corners is fine, we can always dive into WRL proper if we need those last bits of functionality. But something that made the commonly used 90% accessible to ISO C++ developers in a more streamlined and clean way? That'd be nice. Has that been looked into?

    @Glen: as nice as it'd be, all the talk about "do it the right way, and get it standardized" is just unrealistic. "getting it standardized" isn't easy, and there's a lot of opposition in the committee against just adding arbitrary features to C++. The feeling is that the language is already (more than) big enough, so increasing the scope of the standard (for example to encompass COM-like interop functionality) is probably unlikely. And further, even if Microsoft comes up with something that everyone on the committee loves, it'd take the better part of a decade to get it standardized. And Microsoft obviously can't wait that long before making WinRT available to C++ developers.

  • CharlesCharles Welcome Change

    Thanks for the clear questions. I'll pass along.

    C

  • GlenGlen

    Hi @Grumpy (say Hi to Dopey for me!).

    I don't think we are in any disagreement. :)

    My emphasis was as much about "doing it the right way" as it was about getting it standardized.

    To illustrate, I said if more non standard language extensions made it the right way, I'd support it over something that was done the wrong way with less language extensions.

    I was emphasising that the focus has to be about getting it right first, however you do it, because standardizing something that's wrong will be hard and using something that is wrong will be even harder.

    So I share your suspicion that WG21 will never make COM standard. That's why I called for those relevant who support it in that context, or not, to come out and make the case.

    It's also why I pointed out C++/CX forks the road with two notions of class and how I fail to see how it makes logical sense to augment C++ with two non transparent notions of class.

    To maintain an ISO code base, a ref class can only ever delegate to an ISO class, so Microsoft will always be at every border and C++ developers will always be fowarding/wrapping to an ISO class to maintain an ISO code base or giving up all together on that last part. That's not good fo C++.

    C# has none of this problem so why wouldn't people prefer that in many situations where C++ could have been equally good. That's not good for C++.

    C++/CX appears to me as a play for defining how libraries should be constructed in general. To me that means Microsoft wants to own the border of every library not just theirs.

    I fail to see how that is good, but for C++ developers that is terrible if they have to construct the border manually to maintain an ISO c++ code base.

    Regardless, what we have to date remains insufficiently baked and unproven to be right. I don't see any disagreement between us there.

    COM1 was half baked and left C++ devs suffering for years doing the the wiring and the plumbing.

    COM2 is insufficiently baked and still leaves C++ developers doing the wiring.

    C# has none of this nonsense surfaced. One class.

    I am over Microsoft rushing to market with half finished/tested ideas that cause the industry vast amounts of pain, from which they walk away from a while later anyway or extend in an incompatible way, leaving everyone with the mess, including themselves.

    If C++/CX is just a plan to clean up some of that mess, it's not enough. It needs to clean up more of it.

    I think us C++ devs should work out what is right here, regardless of what Microsoft is doing. If they want to go against that, good luck to them. If that challenge instead proves Microsoft right, even better.

    But right now, I don't see how C++ can walk away from this in good shape. If it can, people really need to articulate it because I am at the point where I don't want to use Microsofts tools anymore, the company consistently puts its own motivations above my own and at my expense.

  • GlenGlen

    Do the little things matter? Which customers do I upset with the "not nice" names - my MS customers or my ISO customers? Or just myself because I've brought the two for one deal and polluted the name space with twice as many class names plus I need to remember what that attribute is to fix it and go add it, assuming there is one. For every class in my library.

    class UmHotTubTimeMachineToo
    {
    public:
    void AddPerson( const wstring& personName );
    private:
    vector< wstring > peopleInHotTub;
    };

    ref class HotTubTimeMachine
    {
    private:
    UmHotTubTimeMachineToo ht;
    public:
    void AddPerson( String^ personName );
    };

    void HotTubTimeMachine::AddPerson(String^ personName)
    {
    ht.AddPerson( personName );
    }

    void UmHotTubTimeMachineToo::AddPerson(const wstring& personName)
    {
    peopleInHotTub.insert( personName );
    }

  • DennisDennis

    I agree with Glen.

    > I think us C++ devs should work out what is right here,
    > regardless of what Microsoft is doing. If they want to
    > go against that, good luck to them.

    I agree. I am working it out right now reading this thread. A lot depends on how Herb Sutter answers the questions put forward by the posters here.

    > But right now, I don't see how C++ can walk away from this
    > in good shape. If it can, people really need to articulate
    > it because I am at the point where I don't want to use
    > Microsofts tools anymore, the company consistently puts its
    > own motivations above my own and at my expense.

    I second this too. Walking away from Visual C++ is definitely an option we are considering. We have been burned too many times with things like C++/CLI and now C++/CX, at some point you've got to say enough.

    I would also like to add my voice to the first question by grumpy. With all due respect to Herb, Marian and other Microsoft speakers, what I am hearing from you on borders does not match my own experience. The border for a thing as huge as WinRT is going to be similarly huge. I don't see how one can hope to isolate it from the rest of the codebase short of putting all WinRT stuff into a separate module and guarding that module with a heavy facade (likely organized with C calls and custom handle-like things, as Garfield says, erasing half of the benefits of using the language extension in the first place).

    Do you have any examples of large applications that are now written in C++ and that are going to be moved to WinRT? If using WinRT (and C++/CX) on the border is as simple as you imply, there should be such applications, right? I mean, who wouldn't want to be first to use the Metro UI.

    For the record, this never happened with C++/CLI. The only example of a large application that went from C++ to partly .NET, that I know of, is Visual Studio itself, with its 2010 version. It took a lot of time for the team to even contemplate the move and the results were not good. But maybe C++/CX is different.

    So, once again, the question is: do you have any examples of large applications that are now written in C++ and that are going to be moved to WinRT?

    Thank you.

  • Charles, thanks.

  • Deactivated UserDeactivated User

    Looks interesting.

    And, we have finally obtained (not directly) long awaiting answer to the question: Is COM Dead?

  • PFYBPFYB

    Charles, should we expect an answer from Herb Sutter? I would suggest a discussion in this thread, since it seems to me that the issues at hand are simply too complex for a single all-encompassing answer, a bit of back-and-forth posts would work much better. I would argue that Herb Sutter, the team responsible for C++/CX, and Microsoft in general would benefit from such a discussion at least as much as us here, but... should we expect anything at all?

  • CharlesCharles Welcome Change

    Charles, should we expect an answer from Herb Sutter? I would suggest a discussion in this thread, since it seems to me that the issues at hand are simply too complex for a single all-encompassing answer, a bit of back-and-forth posts would work much better. I would argue that Herb Sutter, the team responsible for C++/CX, and Microsoft in general would benefit from such a discussion at least as much as us here, but... should we expect anything at all?

    As you can imagine, Herb and co are a tad busy. Please be patient. I don't want to pester Herb every day. That said, I agree with you. We should have this conversation.

    How would you feel about us bringing this up in the next episode of GN? You could provide a list of concise questions that we will get the answers to. The number of replies on this specific thread are making it hard to follow along. Jim Springfield won't come on the show (he doesn't want to be on camera and we respect that). Herb's schedule is impossibly complicated and I doubt we will get him, but we can try! So... What do you think?

    C

  • GlenGlen

    @PFYB A discussion thread is an excellent idea, essential.

    @Charles, a future going native show would be great!

    @Everyone

    It's essential the discussion thread come first because the community needs the time and chance to build consensus and clarity of the best ideas and opinions we think Herb should answer to. We have to argue with ourselves first to get the best out; before we waste Herbs time. He and others can always peep in too to see whats coming or to contribute.

    Doing a show too early doesn't allow us to arrive at consensus or clarity and we'll end up presenting Herb with a mix of confused ideas or questions that are not thought through enough or where there is no clear consensus to help Herb prioritise his time on, or where the best ideas still haven't arrived or evolved yet.

    If that happens, we will waste Herbs time with duff or unevolved ideas and questions that he'll reject. Yet we will still feel angry at him because we are still thinking the better answers are out there or he missed it. That wont be fair to him or us but he'll get the blame and we'll keep frothing at him; and you don't know how many goes you'll get at this.

    This is too important for us or MS to mess up.

    Definitely a discussion thread first, an are you ready? question next, then a show to follow. Rinse and repeat if necessary! lol

    Cool stuff.

    Thanks!

  • CharlesCharles Welcome Change

    OK. This is going to happen - addressing these questions on GoingNative. What I would like to do is the following (this makes my life easier).

    @PFYB: Please send me an email with your specific, technical, clear, concise feedback and questions. Just email me at ctorre AT microsoft DOT com. OK? Since others on this thread agree with you, there's no need for folks to send the same questions to me. If you have different technical, clear, concise questions about the C++/CX implementation details, then send them, too. I would ask that you be respectful and not send me rant mails. You can get your rant on here Smiley

    Cool?

    BTW, I spoke to soon about Jim not wanting to be on camera. Perhaps I shouldn't have declared defeat before trying... My apologies to Jim and to you for sharing this assumption. At any rate, we're working to see if we can make this happen for the next episode (could be it doesn't work out due to timing, but it WILL work out at some point).

    For now, please send the technical, clear, concise feeback and questions (especially) directly to me so I have a single place to see questions and not have to parse a thread with over 100 replies and growing.

    We asked you in our very first episode to help us fly this plane. We weren't kidding, my friends. Thanks for the help!

    C

  • @PFYB:

    The main question raised in the thread is:

    ***
    Why, instead of doing C++/CX, did you not use a design that requires no language extensions, eg, by generating C++ wrapper code for consuming WinRT components (similarly to #import) and generating C++ wrapper code for exposing WinRT components (the reverse of #import)?
    ***

    Yes, the "extend TLB #import" option was one of a dozen-plus major alternatives that we considered in considerable detail, including doing some prototyping of a few variations.

    The short answer is that to enable authoring (create new delegates, classes, etc.) in any model inherently requires a lot more information than consumption, because authoring requires complete information to generate the metadata and complex underlying structures. That information has to come from the user, which means he has to provide it somehow -- and again, this is inherent in the problem regardless of the programming model that's chosen. If you pursue the "extend #import" path, you can extend #import itself easy for consumption (which is the easy part) but then for authoring basically end up reinventing a non-ISO C++ MIDL-like language/compiler/toolchain or its equivalent. Not only doesn't that shield the programmer from having to provide all the nonportable non-ISO C++ information he has to provide in any model, but from experience with MIDL et al. we know that he ends up with a programming model that isn't actually simpler in concept count or overall complexity, whose run time performance is often slower (e.g., compiler isn't able to optimize ref counts of smart pointers), and whose tool support is inferior (e.g., debuggers, designers). Now, it would have been simpler for us to implement, which is one major reason we almost did it, but would have been harder to use for authoring and slower.

    Longer answer follows:

    Yes, you can do it... the trouble is the death by 1K paper cuts, because you have to account for detail after detail after detail that needs to be taken care of where the WinRT object model is intricate and fundamentally foreign to the C++ object model (e.g., requires, inheritance, the this pointer, retval mapping, exception mapping, partial classes, more).

    Trying to summarize a months-long design discussion briefly, some of the major (but not only) drawbacks to that approach were:

    • The "more TLB #import" path is wonderful, but for limited consumption only, where by "limited consumption" I mean the ability to use someone else's WinRT API minus delegates and events. Unfortunately, delegates and events are rather pervasive in an async world, so even to do a decent job of consuming an existing WinRT API now requires the ability to do authoring for at least delegates. Whatever programming model(s) we chose had to support full authoring. This is a must-have for us; C++ developers have to be able to express anything. However, authoring requires a lot of information which has to be specified by the user somehow -- on this path you're almost immediately back to a MIDL language and compiler. Saying we should do "the reverse of #import" is easy to say, but elides a lot of details. 
    • Whatever programming model(s) we chose had to also support what we call "high-level" presentation of a WinRT API. The major (but far from only) requirements here are to map the [out,retval] parameters to return values, and mapping HRESULT returns to exceptions -- and both of those in both directions (you can probably see several reasons why consumption is easier, for example because you still need more extensions to let the user provide more information so that everything can be projected correctly). The simplest example is that when you see HRESULT void Method( [out, retval] int i ); in the low-level model, we felt it's very important to present that as int Method(); to the user (which #import could be readily taught to do, but the reverse is much harder in general). The latter is C++; the former is more like C with Classes. This is difficult to do in a #import model; what you need is a toolchain like MIDL or another C++ compiler front-end, which still knows about more information-carrying extensions that the user must write and can parse them out.
    • A major problem is that WinRT inheritance is a very complex pattern, and nearly impossible to do by hand. It's actually implemented using COM aggregation, plus a complex convention of private helper interfaces under the covers that must be followed exactly.
    • Similarly major is interface "requires": Classes implementing an interface, and other interfaces extending an interface, do not really derive from the interface. Instead, they use a "requires" relationship expressed through metadata + QueryInterface, and it isn't a simple matter of emitting a note because it affects code generation, metadata generation, etc.
    • Bunch of other language stuff. For example, there's a nest of thorny issues around the conceptually simple problem of the "this" pointer: What's its exact type? (Note: There are 2-3 obviously correct answers because there are 2-3 different subsets of the use cases, and it turns out that each obvious answer is clearly the right one for its uses cases but fundamentally breaks on the other ones. Sigh.) How do you pass it accurately to another WinRT component, that may be written in another language? etc.
    • Then there's debugging: Briefly, it would make debugger integration and the debugging experience a lot worse. As a very simple example, you'd have to see and step through all the generated wrapper layers and ugliness, whereas we can effectively hide them in the shipping design so that you generally can simply debug the code you wrote. We have some techniques to make some library calls "step-through invisible" but we couldn't cover enough to make it anywhere close to "debug only your own code" seamless.
    • Then there's other tools: It turns out that partial classes are an important ingredient in enabling design tools (e.g., the Jupiter model). The way some of our other libraries work around this using "don't edit here" comments, or "#include <mycode.h> inside a class" textual inclusion, or similar make life harder for the design tool developer while also yielding a worse user experience (e.g., very brittle round-tripping). The biggest reason why C++/CLI never got good design tool support was because it lacked partial classes, and it turned out most of the design tools we'd have liked to have assumed the availability of partial classes and would have been too hard to redesign just for C++/CLI's lack of the feature. We don't want to make that mistake again, but start out on the right foot. FWIW, think partial classes should be considered for C++1y as a standard language feature, just as nullptr, enum class, and other C++/CLI features are now part of C++11.
    • Then performance: There are various cases, some of them common (e.g., aggressively optimizing refcounting) where the resulting code would be slower than in a language-extension in-compiler model because we wouldn't be as able to optimize away performance overheads without that lever.

    So it's easy to say "reverse of #import," but you can't escape the inherent complexity in the problem domain that the user has to be able to express, regardless of the model. So to be viable this path has to grow a full-blown "actually a full MIDL language/compiler and toolchain" model. That doesn't save the user from expressing all the nonportable code and extensions anyway, but would require him to use a more complex toolchain, learn more variant language annotations/extensions, write more code to do the same job, often run more slowly, and have inferior debug and other tool support.

    Having said that, what if you really only want to do consumption, which #import does make pretty nice, and wish you had a #import model? Then my answer is that we basically have it: The C++/CX #using story is actually similarly lightweight. If really want to do "only consumption" in C++/CX you can ignore all of the other extensions besides just #using, ^ and ref new. Done, everything else is seamless -- interface "requires" and class inheritance are exposed as normal C++ inheritance, [out,retval] is wrapped to a return type, HRESULTs are mapped to exceptions, etc. Maybe that's an option to consider.

    And there's definitely WRL.

    Thanks,

    Herb

  • CharlesCharles Welcome Change

    Wow. I think that about takes care of that. Thank you, Herb!

    "Patience, grasshopper"... I should of taken my own advice...

    So, let us know what you want for the next episode. Do we really need to cover this now that Herb has answered the key question -  and very clearly and in detail?

    C

    PS: I'll answer my own question: Yes. Yes we will. We will talk to Jim about C++/CX internals and implementation (this current episode was focused on the design) and learn more about the overall system that it targets... If you still have technical questions after absorbing and digesting Herb's reply, feel free to send them along.

  • GlenGlen

    @Charles

    It sounds like you just ignored my opinion that that wasn't the only key question, and that preparation is required, and that a discussion thread exactly allows for that?

    I saw no acknowledgement of that at least.

    Until then I said I suspect most answers Herb gives wont satisfy.

    Infact, I'll ask. @Everyone: Who's satisified with the latest answer? I suspect nobody (that doesn't mean Herb is wrong). But until people have thrashed out with clarity amongst themselves what the issues are and the potential solutions - the things that it took Herb a month to thrash out with his team, we wont get it.

    Best thing Herb can do is publish the C++/CX Design Rationale (his conclusion of that month of thrashing) and let us pick that to death before he bakes the pie.

    In absense of that and regardless of that, the rest of us are best thrashing that out ourselves and see where we agree with him.

    There are other key questions. Sending our questions all to you or Herb in private doesn't allow people to work together to share and evolve the right ideas together and develop a public understanding and consensus.

    Not all of us are stressed about extensions, for example, (as I have made every effort to say already), but some of us are stressed that they need to be the right ones.

    Now before you go and ask me what they are: the answer is already given. I'm not sure yet, its complex as Herb says.

    But we need the input from other people to help agree with others and formulate for ourselves what the key questions are.

    I can't even be sure that my own KEY issues actually are KEY issues for me or anyone else without that discussion and input from the other guys here, let alone anybody elses.

    A discussion thread is what is needed and thats how we help you fly the plane without waisting Herbs time.

    Who agrees / disagrees?

  • HoudiniHoudini

    Does anybody feel stupid after Herb's explanation? It's like looking at the hands of an illusionist :-) We know that CodeGear C++ Builder or Qt models feel like standard C++, consumed and authored like almost standard C++, debugging of that code is just like any other C++ code. Yet, C++/CX being the one true way, is causing shivers down the spine. Is the real reason for the existence of CLI/CX/whatever-comes-next in the fact that "WinRT object model is intricate and fundamentally foreign to the C++ object model," and therefore no matter what we do, we'll have to torture C++ into submission to that object model? I feel like demanding, give me the old C WinAPI back, I know how to wrap it into C++ classes, I know how to create events and properties in C++, and keep the CX, thank you.

  • GlenGlen

    Well Houdini,

    THAT is exactly a KEY question that I already asked earlier. "Is is any object model that is so Foreign to C++ justified.".

    However, C++/CX isn't a QT or a Win32, it isn't a library. It is a wrapper for ALL libraries (feel free to argue that), and yes it does require you to contort your C++ do support it.

    Is that "contortion" justified, how can or should it be automated is the question that leads to a million other questions.

  • CharlesCharles Welcome Change

    @Charles

    It sounds like you just ignored my opinion that that wasn't the only key question, and that preparation is required, and that a discussion thread exactly allows for that?

    I saw no acknowledgement of that at least.



    Not sure why you're saying this... I'll quote myself: "If you have different technical, clear, concise questions about the C++/CX implementation details, then send them, too."

    In terms of your question "is any object model that is so foreign to C++ justified", I'm not sure you're asking the right people. Herb and the VC++ team didn't design WinRT. The Windows team did. And their design isn't as foreign to C++ as you seem to suggest... Think about the problems they set out to solve. Watch some BUILD sessions on WinRT internals. Read some WinRT documentation. Perhaps you already have, so forgive me if I'm being pedantic.

    The topic here is C++/CX. Now, obviously, C++/CX exists only to make C++ programming on WinRT productive for C++ developers - WinRT objects written in C++ are readily consumable by other Metro components, some of which will be written in VERY different languages and running in foreign virtual machines (CLR, Chakra)... You can write low level COM to get the job done using WRL. We keep saying this for a reason. That strategy, however, hasn't been fully documented yet, so it's fair for you to ask "but what does that really mean in practice?"

    Herb clearly explained the rationale behind not employing one proposed model to solve the problems at hand (consuming and authoring shared components in the "Windows 8 Metro style"). Right? What's missing from his answer, exactly? Again, we're not talking about the design decisions behind WinRT itself. You can imagine a lot of thinking and planning and high quality engineering went into that design, too.... Step back and think about what WinRT affords: efficient interop between very different runtimes in a coherent, predictable and reliable application execution environment. Why should C++ developers have to write the gnarliest code to play in this modern sandbox? Can't C++ developers get some productivity with their coffee, too? This part of the equation is seemingly ignored in this thread... Does productivity not matter to you at all? Of course it does!

    This thread is not the right venue for the WinRT conversation... That must happen in a place where Windows engineers frequent - the Windows 8 forums.

    Finally, we will sit down with Jim and hash this out - the C++/CX internals stuff. What questions - related to C++/CX's implementation - do you have for Jim?

    C

  • GlenGlen

    Charles

    I read what you said the first time, but did you read what I said in reply? If you did, I don't understand why you repeated yourself?

    You said:

    "If you have different technical, clear, concise questions about the C++/CX implementation details, then send them, too."

    To that, I'll quote myself:

    "There are other key questions. Sending our questions all to you or Herb in private doesn't allow people to work together to share and evolve the right ideas together and develop a public understanding and consensus."

    Which bit of that didn't you get?

  • CharlesCharles Welcome Change

    @Glen: You made it sound like you were being ignored. The point of the email is so I can have a single source list of questions to raise in the interview with Jim Springfield. You are free, as a group, to have any conversation you'd like. For my selfish purposes, this particular thread is becoming a bit large and cumbersome (what are the questions, again? Wait, didn't we already answer that one? Etc....). Productivity is important to a content schmuck like me, too...

    C

  • @Charles && Everyone:

    Could any of you ask mr sutter the question I've asked and didn't get an answer to it:

    Ok, the question was/is:

    Could that (the goal of C++/CX) be achieved without modifying syntax and semantics of C++,

    if no, why? What is it in CX that couldn't be done using existing language futures + compiler's help + other (if necessary) tools help?

    if yes, why did Microsoft do that?

    I would really appreciate if you could ask mr sutter and if he would be so kind and reply to them, with presenting examples and counter examples of code that clearly show that what you did with CX was the only and best way to go and it could not be done with C++.

    Regards

  • This is madness.

    First, I read a post by Charles and this post gives me hope.

    Then, I read a post by Herb and I seee that he more or less ignores everything we are saying without any deep thoughts and essentially answers us with a single phrase -- "Saying we should do "the reverse of #import" is easy to say, but elides a lot of details." -- then spends the rest of the post either restating points that have already been discussed a number of times, or bringing up tangential issues... Sigh.

    Sorry in advance for the long post, I split it into parts for easier navigation.

    TLDR: I am deeply dissatisfied with the post from Herb. I am tired of answering the same old points ad infinitum. I suspect Herb didn't read the thread. I suspect he won't. Such is the "discussion" we are having here.

    Part 1: old points: rehashed

    Let's walk through the bullet list. The first half consists completely of things we have already discussed at length. I get an impression that Herb did not read the thread at all. In fact, I get an impression he didn't even read my reply. Here goes:

    * "The "more TLB #import" path is wonderful, but for limited consumption only, where by "limited consumption" I mean the ability to use someone else's WinRT API minus delegates and events." -- We have been over this already a number of times. With #import, one can consume WinRT API. Since delegates and events require exposing parts of your own code to WinRT, #import does not help with that, so if you only have #import you can not consume delegates and events. You have to have something else besides #import. We suggest this something else can be the reverse of #import. With both #import and the reverse of #import, one can consume WinRT API including delegates and events.

    * "Whatever programming model(s) we chose had to also support what we call "high-level" presentation of a WinRT API. The major (but far from only) requirements here are to map the [out,retval] parameters to return values, and mapping HRESULT returns to exceptions -- and both of those in both directions ..." -- We have been over this a number of times as well. Wrapper code generated by #import and the reverse of #import absolutely can map [out,retval] parameters to return values and vice versa. Similarly, it absolutely can map HRESULTs to exceptions and vice versa.

    "This is difficult to do in a #import model; what you need is a toolchain like MIDL or another C++ compiler front-end, which still knows about more information-carrying extensions that the user must write and can parse them out." -- Yes, it is difficult to do the reverse of #import with #import (doh). Nobody suggests you do this. We suggest you generate wrapper code for exposing C++ classes to WinRT in the compiler, using a logic similar to the one you employ for generating metadata out of ref classes. Alternatively, move that logic into a separate tool. Before you say so, yes, we realize this logic is going to be different than the one you are using for ref classes right now. In some respects, the new logic would be more complex, since C++ is more expressive than C++/CX. On the other hand, the new logic would only have to support C++ without the features added by C++/CX.

    * "A major problem is that WinRT inheritance is a very complex pattern, and nearly impossible to do by hand. It's actually implemented using COM aggregation, plus a complex convention of private helper interfaces under the covers that must be followed exactly." -- It seems we have to restate *again* that we suggest using a combination of #import (not relevant to this point, but I will repeat it) and the reverse of #import. With the reverse of #import, we suggest you take classes with the natural C++ inheritance and turn them into classes with WinRT inheritance. Can this be done? Yes. Does it matter how hard it would be to do this by hand? No, since we suggest that you do this via an automatic tool.

    * "Similarly major is interface "requires": Classes implementing an interface, and other interfaces extending an interface, do not really derive from the interface. Instead, they use a "requires" relationship expressed through metadata + QueryInterface, and it isn't a simple matter of emitting a note because it affects code generation, metadata generation, etc." -- Ooohh... Again, we suggest that you take care of this by generating wrapper code for C++ classes that have to be exposed to WinRT. Can this be done? Yes.

    Seriously, Herb, we have been over all of the above points at least twice, I can't believe you are still bringing them up without any changes. If you, say, showed us example C++ code with inheritance which would somehow translate into WinRT badly, that would be quite different, but you are simply reiterating the points which we believe we have already answered, more than once! Why do this? Please read the thread. Sigh.

    Part 2: new points: tangential or bizarre

    The rest of the list consists of relatively new points, however, most of them are very tangential to C++ and neither is convincing in the least. Here goes:

    * "Bunch of other language stuff. For example, there's a nest of thorny issues around the conceptually simple problem of the "this" pointer: What's its exact type? (Note: There are 2-3 obviously correct answers because there are 2-3 different subsets of the use cases, and it turns out that each obvious answer is clearly the right one for its uses cases but fundamentally breaks on the other ones. Sigh.) How do you pass it accurately to another WinRT component, that may be written in another language? etc." -- It is not clear at all what you are talking about. It is even less clear how this advances the case for C++/CX. You say that no matter how one answers the question you are posing, he is wrong, and there are equally valid alternative points of view. Good. What is it exactly that C++/CX does right here that C++ can't do? If you are talking about the problem of identity as regards an object implementing multiple interfaces, this is not a new problem neither for C++, nor for COM, nor for WinRT. This problem certainly exists in C++/CX as well. If you are talking about something else, please be more specific.

    * "Then there's debugging: Briefly, it would make debugger integration and the debugging experience a lot worse. As a very simple example, you'd have to see and step through all the generated wrapper layers and ugliness, whereas we can effectively hide them in the shipping design so that you generally can simply debug the code you wrote. We have some techniques to make some library calls "step-through invisible" but we couldn't cover enough to make it anywhere close to "debug only your own code" seamless." -- First: What??? You break the language with an extension that is not going to be supported by anybody but Microsoft, thus denying us use of any debuggers and helper tools except those you have chosen to provide yourself (and your debugger does have its own set of bugs and performance problems, mind you), yet you are talking about providing better debugging experience?! You don't even consider this angle, do you? This angle is huge.

    But let's try and think about what the debugging experience with wrapper classes would actually be, as compared to C++/CX:

    a) You make a WinRT call implemented by the system. In C++/CX you do F10 and get a result. In C++ you can do F10 and get a result (same as in C++/CX), or you can do F11 and step through a couple of times into the wrapper code until you meet the actual system call, then you do F10 and step out. No difference.

    b) You accept a call from WinRT into your own function. In C++/CX you place a breakpoint into your function, wait, get hit, go from there. In C++ you do exactly the same. No difference.

    c) You make a WinRT call which eventually returns to your own function? Let's try. In C++/CX you place a breakpoint into the callback function which is supposed to be eventually called through WinRT, then F10 over the original call, get a hit on the breakpoint, and proceed from there. If you look into the stack, you will see your original call, a bunch of WinRT calls, then your callback. OK. In C++ you place a breakpoint into the callback, then F10 over the original call, get a hit on the breakpoint, and proceed from there. In the stack, you see your original code, a bunch of WinRT calls and calls through wrapper code (this is where the difference is), then your callback. So, that's it, a couple of extra calls that you see in the call stack? And that you may sometimes have to go back through them if you want to trace the path of your return value from your callback to your function that made the original call to WinRT? Isn't it a bit far-fetched? Is this all there is?

    Which debugging scenario did you have in mind, Herb? I fail to see where exactly the debugger experience would be so much worse than with C++/CX. Yes, you will sometimes see a couple of extra entries from wrapper code on stack, and you might sometimes have to manually get out of them (and maybe - very rarely - have to manually get into them), but... is that it? If so, that's a very minor inconvenience, and certainly not a reason for forfeiting C++ in favor of a language extension.

    * "Then there's other tools: It turns out that partial classes are an important ingredient in enabling design tools (e.g., the Jupiter model). The way some of our other libraries work around this using "don't edit here" comments, or "#include <mycode.h> inside a class" textual inclusion, or similar make life harder for the design tool developer while also yielding a worse user experience (e.g., very brittle round-tripping)." -- Let's disregard for the moment support for partial classes possibly coming to C++11. What's wrong with "don't edit here" comments? If you do edit the code inside those comments, you might break it so that the designer won't recognize it, fine. But if you edit the code inside a file generated by the designer, you might break it, too. This whole "story" behind partial classes is not that partial classes magically allow the designers to not be broken anymore, it is that partial classes merely take the code generated by designers out of the way. The code *can* still be broken, by an inattentive developer or by an ignorant tool. You get a couple of new problems, too, since you have to take care of additional files (eg, since your code now lives in more than one file, the files can now get out of sync, in particular, you have to remember to update / commit / checkin / checkout / whatever verbs your VCS uses these files as a whole - this is a new problem which you might not have had before). Some might say that the cure is worse than the supposed "disease". Finally, if you wanted partial classes so much (even though it baffles me as to why), given that this feature is eyed by the standard folks, there is no reason you couldn't have added partial classes to C++ instead of inventing C++/CX. Yes, we would be unhappy with you altering the language in non-standard ways, but that would be infinitely better than what you are doing with C++/CX.

    * "Then performance: There are various cases, some of them common (e.g., aggressively optimizing refcounting) where the resulting code would be slower than in a language-extension in-compiler model because we wouldn't be as able to optimize away performance overheads without that lever." -- Oh. This final point is *complete* BS. Here is why:

    First, "aggressively optimizing refcounting" is so small, you should not be bringing it up. Yes, AddRef / Release pairs are costly in the world of multiple CPUs, but precisely for this reason we have long knew not to AddRef / Release repeatedly in tight loops (obvious to any developer after he knows that AddRef / Release have to sync all CPUs and this costs time), and not to make interfaces chatty (obvious to any developer dealing with any kind of "borders", using your terminology). If someone is not following either of these principles on a critical path in code, his performance problems will be much more serious than just AddRef / Release. And for anyone who does follow these principles, there are no AddRef / Release pairs which you could optimize away! Seriously, saying that you are going to "aggressively optimize refcounting" is like saying that you are going to find all cases where a developer increments a variable, then immediately decrements it, without doing anything in between, and remove this. Nobody does this!

    But, more importantly, let's be clear on what you are doing with C++/CX. Overlook the fact that you are taking development resources which could have been spent on C++ - eg, on making the generated code faster - and redirecting them onto your proprietary extension. Overlook this. What you are doing is much worse, you are making us write code that nothing else besides Visual C++ will be able to compile. In terms of performance, you are locking us into whatever optimizations you will choose to do in Visual C++. This lock in *alone* loses us so much performance, it is not funny! We *do* care about the performance. We *do* use other compilers and tools other than compilers (eg, code analyzers) to get the best performance we can. With C++/CX, we *won't* be able to use these compilers and tools. This *will* make our code slower than it otherwise would have been, by a significant amount. Is your compiler the best there is in terms of optimizing C++ code? No, the quality of the code you generate is fair, but that's it. In fact, on modern optimization techniques, you are way, waaaaaaaay behind others. I am not even talking about code analysis. Losing the ability to use tools other than yours can't even begin to compare with "aggressive optimizations of refcounting".

    You might say that I don't have to use C++/CX in the performance-critical parts of the code. Calmly, if the performance-critical parts of the code should be in C++ and not in C++/CX, you shouldn't even be making a point on "aggressive optimizations of refcounting", since these optimizations can't play a role. If, on the contrary, the performance-critical parts of the code should be in C++/CX, see my note on your "aggressive optimizations of refcounting" being a toy and the vendor lock-in occurring from using C++/CX having much more a say in the final performance than any of optimization you could ever possibly make.

    End of bullet list.

    Part 3: summary

    Now, I know you are tired, but let's return to this signature phrase of Herb which is essentially his answer to everything we have been putting forward in this thread:

    "Saying we should do "the reverse of #import" is easy to say, but elides a lot of details."

    Herb, we know that saying "the reverse of #import" elides a lot of details. We asked you to provide the details which would make doing the reverse of #import impossible or very difficult, much more difficult than doing C++/CX. This was the point of the discussion.

    You have not provided these details. You restated all of the old points, many of which had no bearing to doing "the reverse of #import" at all, and have thrown in a couple of new points all of which are tangential and very questionable. You did not provide any specifics to anything.

    The question still is:

    Why, instead of doing C++/CX, did you not use a design that requires no language extensions, eg, by generating C++ wrapper code for consuming WinRT components (similarly to #import) and generating C++ wrapper code for exposing WinRT components (the reverse of #import)?

    Can you answer this question? Sorry, but ""the reverse of #import" elides a lot of details" is not an answer.

    You are free to call me a ranting fool, Charles, and you are free to say things like -- "Wow. I think that about takes care of that." -- but the truth is that no, this answer from Herb does not take care of that at all. It does not answer anything. It answers nothing at all.

    Sigh.

    I don't know if it makes sense to continue. I would be all too happy to make a post or email or whatever with nothing but technical points and no rants, but... for what purpose? You just don't listen. You are lecturing us.

  • GlenGlen

    @Charles, I don't think you read a worse I say. If someone else wants to translate to charles where the mismatch is in what I'm saying to what he's hearing, please do. If it's me, equally, tell me. I'm over it for today.

    In the mean time, @PFYB good luck. I'd like to talk to you privately if we get a chance.

    Charles, could you please give PFYB my email address. PFYB, drop me a line, but no worries if you'd rather not.

  • WarrenWarren

    Charles,

    > Do we really need to cover this now that Herb has answered
    > the key question - and very clearly and in detail?

    I strongly disagree that Herb Sutter answered the key question as put forward at the top of his own post.

    I am seriously disappointed that instead of answering that question, Herb has chosen to mostly restate the same old points which have been abundantly addressed before, including in replies to Herb's previous post. Take the requirement to map [out, retval] parameters to return values. It has been explained a number of times that this is a non-issue, if you can generate wrapper code, you can take care of this. Why bring this up again? Is Herb unaware of how we are proposing to address the issue? If so, he should read the thread. Does he disagree that the way in which we propose to address the issue will solve it? If so, he should point out exactly why. If neither is the case, there is no reason to beat this dead horse again. Disappointingly, most of points in the list provided by Herb are like this.

    I am also disappointed that Herb decided to pad his list with ruminations on various side-effects of the current implementation of C++/CX masquerading as genuine reasons for its existence. Such is his point on performance. Herb, do you really want to say that one of the reasons to choose C++/CX over plain ISO C++ is performance? If this has been a design goal, could you please explain to us how you fulfilled it? How exactly is C++/CX is going to be faster than C++? What did you do in this area, what measurements did you perform, what results do you have to show? Someone on the team saw a low-hanging fruit and decided he can save a pair of calls to AddRef and Release, fine, but let's not be silly here, this does not at all mean that C++/CX will suddenly beat C++ in terms of performance. If you really mean that C++/CX is genuinely faster than C++, go ahead and make your case! We are C++ developers, we will kill for performance. If you can't or won't make this case, stop pretending it has been made already and take the relevant item off your list. Stop insulting our intelligence. We aren't idiots, we can tell a genuine argument from a half-baked afterthought.

    I also note that there was nothing said on borders. This issue has been raised many times on the thread and is extremely important.

    I hate to do this, but just so we are really, totally clear:

    > Herb clearly explained the rationale behind not employing one
    > proposed model to solve the problems at hand (consuming and
    > authoring shared components in the "Windows 8 Metro style").
    > Right?

    No.

    > What's missing from his answer, exactly?

    Herb didn't provide an answer to the question at the top of his post. If you think he has, please answer in your own words: can generating wrapper ISO C++ classes do everything C++/CX can do? why Microsoft have chosen to go with the latter and not the former? I can't see the answer to this in Herb's post.

    We need a real answer.

  • Glen: my email address is, without extra tokens: prae nospam tor271 at hotmail blabla com.

  • DennisDennis

    @hsutter

    Your post is, indeed, thoroughly disappointing. Very briefly, with my words in parens...

    So it's easy to say "reverse of #import," but you can't escape the inherent complexity in the problem domain that the user has to be able to express, regardless of the model. (Really? We ask you why you think addressing that complexity while staying in C++ is worse than rolling out a language extension, and your reply is "there is complexity"? Really?)

    So to be viable this path has to grow a full-blown "actually a full MIDL language/compiler and toolchain" model. (You are willing to do a full-blown compiler and toolchain for C++/CX, but not for C++? How is parsing C++ code and generating other C++ code significantly more difficult than parsing C++ code and generating metadata?)

    That doesn't save the user from expressing all the nonportable code and extensions anyway, but would require him to use a more complex toolchain, learn more variant language annotations/extensions, write more code to do the same job, (Huh? How so? What is so difficult in marking up language elements you want to export. You already have declspec, you already have export "C", you can extend either. You can always use #pragma export(winrt, start) ... #pragma export(winrt, stop). There are other solutions as well. What is so difficult? Where is all the additional code you are talking about? Where is a more complex toolchain?)

    often run more slowly, (How so? Are you referring to your optimization of refcounts? Seriously, what effect does this have on the final performance? Geez.)

    and have inferior debug and other tool support. (Really? Inferior debug and other tool support? Can we debug C++/CX in WinDbg with the same level of support as for other non-C++ technologies like .NET? I strongly suspect we can't. We can debug C++ though. Yet you say it is C++ that gets inferior debug and not C++/CX. It is the reverse! Same for tools.)

    I agree with PFYB, you, guys, just don't listen. This looks hopeless.

  • jalfjalf

    One thing that makes C++/CX feel icky to me is that it seems to go beyond what's strictly needed. Instead of a shared pointer (or instead of simply building the ref-counting into the C++ representations of WRT types), we get the ^, which, well, how does this play together with C++?

    How do the std type_trait classes behave with hats or all the other C++/CX "magic" bits? Something like a wrt_ptr<String> would fit into the language, I'd know how it behaved, it wouldn't have weird corner cases that require me to write *more* nonstandard code. (See the list PFYB showed, of standard C++ constructs which just don't work with these "magic" types.

    So by introducing non-C++ types into my C++ code, it cuts me off from writing the surrounding code in C++. And then, am I really writing C++ at all?

    Another example is partial classes. They're not necessary for interop with WRT. They're not even *necessary* for designer-generated code, they just make life a bit easier for the people writing the designer. But they were crammed in there anyway, because, apparently, the cost of adding language extensions is near zero.

    Is the "ref new" keyword necessary? Why not just a CreateInstance<T> function?

    I really wish C++/CX hadn't tried to do so many things. I wish I could get the bare minimum of extensions required to interop with the Windows Runtime. Convenience syntax for reference-counting is not necessary, partial classes are not necessary, and magic "ref new" keywords are (as far as I can see) just not necessary to achieve the stated goal of C++/CX. They offer a very small amount of additional convenience, at the cost of introducing new syntax, and making it harder/impossible to fit C++/CX code into C++.

    And I wish that these extensions had been more cleanly separated from C++. A different file extension, perhaps, would have reinforced the notion that C++/CX is intended for use at the boundaries only. Say we use the .cx extension for C++/CX code. Then the compiler can default to C++/CX extensions enabled on .cx files, and disabled on .cpp files. And then we would have some relatively clear separation. Something that can still be overridden if need be, but which, by default, slaps us over the wrist if we accidentally start writing hats or other CX syntax into our "core" C++ code. Intentionally or not, I'm concerned that C++/CX effectively breaks C++ code.

    Sadly, I still get the impression that Microsoft were working under the assumption that "as long as it's native, everything is ok". I get the impression that to Microsoft, the whole "boundary only" thing was of academic interest only: that none of Microsoft's code was actually developed this way, and that no thought was given as to how this separation could be enforced, either by the toolset or in the design of the language extensions.

    Anyway, I think most of the frustrations with C++/CX have been made clear by now. Would it be possible (either here or somewhere else) to start a constructive discussion about how this could/should evolve in the future? If C++/CX 2.0 could be developed with a b it more community input and feedback, it might be better received.

    Like I said, I think a clearer separation between C++ and C++/CX would go a long way towards fixing my concerns. And with a few simple extensions, standard C++ wrappers for many C++/CX constructs could be created, allowing C++/CX code to interact more naturally with C++.

  • I've just discovered this very interesting thread, and spent quite a while to read it. I would like to thank Herb, Charles, et al. because they want to hear what we have to say. I'm not sure the Windows guys are listening to what we say.

    Here is what I think about C++/CX, for what it's worth. I totally agree with what other C++ devs say here.

    I have written a few C++/CX lines of code, and the feeling I have is, a C++ app which uses WinRT is not a C++ App. It is not using C++, it is something else.

    At some point I was trying to figure out how to use one particular WinRT object. I found a Javascript sample, nothing in C++ or C#. The Javascript sample let me understand how it works. I was able to translate the code from Javascript to C++/CX and C# on a line by line basis. That was straitforward. Same WinRT types, same instructions, the syntax differs. So with C++/CX we can share our code base with C# and Javascript developers, isn't that wonderful?

    I haven't written a full featured app in C++/CX with a data layer, presentation layer, etc, Only a few code samples. But in all the code samples I wrote, there was no "thin boundary" to WinRT. All the code had to use C++/CX in some way: an API call, a callback or a system type (I hate Platform::String). WinRT is using async calls, this is great, but it is WinRT C++/CX parallelism. Of course I could have created some layers, but the WinRT interface layer and the layer boundaries would have been far bigger than ISO C++ code itself. This is really worrying me.

    The other thing that is worrying me is, you can translate C++/CX code into C# and Javascript on a line by line basis. I haven't tried VB though. I don't like this "one size fits all" idea. 10+ years ago there was Visual C++ on one side, and Visual Basic on another. 2 different languages for different purposes. Then .Net guys thought one pattern would fit all. They even tried to build Windows in C#/.Net, but they failed. Then they had this great idea of writing .Net framework in native code, and now they can build Windows using .Net, well WinRT. And this great marketing phrase: you can use fast and fluid C#, Javascript, VB, C++, whichever you like, to build Windows Applications! 

    This is worrying me because Microsoft already said that 10 years ago with .Net. Problem is, there is only one model, and the languages (except C#) have to be distorted to fit WinRT concepts.

    In June 2011, when I heard rumors that Microsoft would go native, I thought Windows guys would build some native framework we could use in C++, and build a CLR layer on top of it so it could be used in C#. But Windows team did not do this. They built a native framework with a CLR-compatible interface (WinRT). And we are trying to use this interface in C++, although it is designed for C#. How disappointed I was two months ago!

    This is the first point. OK it has nothing to do with C++ team, it is Windows team.

    The second point is C++/CX itself. IMO, it is designed to look like C#. Marketing point. In fact it is really easy to translate C++/CX code into C# or VB and vice versa but do we care? WinRT is really pleasant to use in C#, it has been designed for that. Then the C++ team had to find something to make WinRT work with C++. You did it the C# way, not the C++ way. C++/CX is C++ distorted to fit C# design. So where is the point using C++/CX instead of C#?

    As other guys here, I do beleive there is another fast and fluid way to use WinRT in C++. But maybe this other way of using WinRT in C++ is too far from WinRT concepts. Why creating a new design with WinRT if you don't use it in C++?

  • ISO 14882ISO 14882

    PFYB: "Now we have the third extension, C++/CX. Sigh... Microsoft never learns."
    Warren: "can generating wrapper ISO C++ classes do everything C++/CX can do? why Microsoft have chosen to go with the latter and not the former?"

    Maybe because this is what MS is just used to as a company having a long history of "embrace, extend and extinguish"? Quoting Wikipedia:
    "The strategy's three phases are:
    Embrace: Development of software substantially compatible with a competing product, or implementing a public standard.
    Extend: Addition and promotion of features not supported by the competing product or part of the standard, creating interoperability problems for customers who try to use the 'simple' standard.
    Extinguish: When extensions become a de facto standard because of their dominant market share, they marginalize competitors that do not or cannot support the new extensions.
    The U.S. Department of Justice, Microsoft critics, and computer-industry journalists claim that the goal of the strategy is to monopolize a product category."

    Doesn't it look familiar?

  • GlenGlen

    @Pierre

    You don't wrap WinRT, it's not a library. Its design purpose is to wrap your library, C++/CX's job is to get underneath you. That's why the border matters despite people saying it's "just" the border. The difference is, it's your border, YOUR library.

    It's a language within a language to do exactly that.

    People, please come out and challenge this statement. I'm happy to be wrong. But this is the core of it.

  • CharlesCharles Welcome Change

    @Glen: What am I missing? I answered your question: You are not being ignored. I also attempted to add some logical reasoning behind the complexity at play here: WinRT provides the Windows 8 Metro Style Application object model. Not VC++. You should therefore engage the Windows people, too...

    I read Herb's reply and what I read was: Yes, we could have provided the model suggested in terms of some "reverse of #import"... But, this would have added a lot of complexity for everyone involved, including, and most importantly, end user C++ developers targetting Windows 8 Metro.

    It seems to me that my comment on the developer productivity gains and ease of consuming and authoring WinRT objects originating or targetting different WinRT-compatible languages that C++/CX affords is simply being ignored. Why is that, exactly?

    C

  • Charles wrote

    It seems to me that my comment on the developer productivity gains and ease of consuming and authoring WinRT objects originating or targetting different WinRT-compatible languages that C++/CX affords is simply being ignored. Why is that, exactly?

    C

    About productivity gains using WinRT, well I'm not sure. When I use WinRT, I always have to care if I am using a WinRT type or a C++ type, and write code to convert from one to another. Am I using a wstring here? Oh but I need a Platform String. Same for containers. You can see this problem in Marian Luparu's demo in the video. Most of his code is about type conversion. And you can also note that there is no "thin boundary" at all. All his code is using WinRT types. OK it is just a small sample, but still.

    About the ease of merging different languages in the same application, well you are right, it is easy to author a C++/CX module and use it from a C# object. But why would I use two or more languages if I can use one? Using 2 languages makes the project maintenance at least twice as hard. You need maintain the compatibility with two languages instead of one. You also need dual competence developers, etc. Why would I do that if I can avoid it?

  • @PFYB wrote: "I suspect Herb didn't read the thread. I suspect he won't. Such is the "discussion" we are having here."

    Note that this is now a 32,000-word thread. That's half the word count of Exceptional C++.

    So I appreciated that @PFYB agreed to identify a key question, which can reasonably be answered:

    @PFYB asked: "The main question raised in the thread is: *** Why, instead of doing C++/CX, did you not use a design that requires no language extensions, eg, by generating C++ wrapper code for consuming WinRT components (similarly to #import) and generating C++ wrapper code for exposing WinRT components (the reverse of #import)? ***"

    Yesterday I put aside other work to spend a couple of hours writing a thoughtful answer, without evasion and in reasonable detail, including: a pointer to detailed discussion of many of these points in my 54-page A Design Rationale for C++/CLI; that we had tried and prototyped this and other options; and summarizing some highlights of what we learned over the course of about 18 months (end to end, the intensive part was about a year), during which time WinRT itself was still in flux and we had to both influence its design and accommodate the directions it might go.

    @PFYB responded in part: "I am deeply dissatisfied with the post from Herb [that answered exactly your question]. I am tired of answering the same old points ad infinitum [so evidently others have already given you the same answers to the same question]. I suspect Herb didn't read the thread. I suspect he won't. Such is the "discussion" we are having here."

    Wow.

    You're welcome. Sorry that I can't be helpful.

    Herb

  • GarfieldGarfield

    Just wanted to touch on "It turns out that partial classes are an important ingredient in enabling design tools ... FWIW, think partial classes should be considered for C++1y as a standard language feature."
    I wish to see the latter being discussed by committee members, I'm somehow skeptical about them agreeing on adding this feature to the language.
    Firstly, the claimed benefit is limited to "enabling design tools." -- Can we keep expanding the standard with new design tools constantly coming and going?
    Secondly, I don't even think that's the only or even best way to build design tools. Visual C++ already has "#pragma region" to mark and collapse designer generated code, it works pretty good. IDE could even have made this portion read-only. The interaction of designer generated code with user input is also nothing new -- Borland designer, for example, would merge the user changes, providing seamless integration of user-defined and designer-generated code.
    Finally, I found reading and debugging partial classes (using C#) a lot worse experience than dealing with normal C++ classes, so I doubt C++ folks will like this either.

  • CharlesCharles Welcome Change

    , pierremf wrote

    *snip*

    About the ease of merging different languages in the same application, well you are right, it is easy to author a C++/CX module and use it from a C# object. But why would I use two or more languages if I can use one? Using 2 languages makes the project maintenance at least twice as hard. You need maintain the compatibility with two languages instead of one. You also need dual competence developers, etc. Why would I do that if I can avoid it?



    It is also easy to consume a WinRT module written in JavaScript inside your C++/CX code. That's also important. This isn't really about you using multiple languages yourself in a single project - though it certainly could be the case that you would want to, say, build a UI layer in HTML5 (HTML + CSS + JS) and write the core application logic/algorithms in C++ or use XAML for the UI layer, etc... It's certainly possible, though somewhat far-fetched, that you would want to write an app that uses C#, JS and C++, but, implicitly, you probably will be doing just this: You will be consuming components across language boundaries (they could have been authored in C++, JS or C#...), many of which are not written by you... That's a key point.

    It seems to me that in the C++ case, these types of shared WinRT objects will often be authored by you, the kings of high performance and high output computing -> C++ developers. The core of what you author - the algorithms - will not be written in C++/CX because they don't need to be. They will be written in C++.

    Do an experiment, if you will. Take an existing physics library or math library or image processing library writtten in C++. Create a Windows 8 Metro C++ app. Create a shared module out of it. Do this with C++/CX at the boundary (so, the insides are written in C++, the skin on the outside is written in C++/CX). Now, do this same thing (the boundary, the shareable skin) in WRL. You tell us which is harder, which is more insane, which is too complex.

    This hybrid application environment that WinRT supports seems to me to be the most compelling thing about it. As you learned in the BUILD sessions on Windows 8 Metro Style Applications and WinRT, there are compelling user-centric features provided by the underlying system that your application can take advantage of for free, but only if you play by WinRT's rules (again... WinRT defines the model, not the languages used to program WinRT apps...).

    The whole point of C++/CX is to make your life easier in this hybrid world of Metro style apps. If you have no interest in playing in this heterogeneous sandbox (authoring and consuming WinRT objects written in very different languages), then you don't even have to consider C++/CX at all. Even if you do ( queue the broken record Smiley ) you can use WRL entirely, but you will be writing some very gnarly COM code and that's OK - it's up to you. Once there's more documentation about WRL, perhaps this will become clearer.

    Thanks for having this conversation with us.

    @Everyone: As I said already, we will dedicate another GoingNative episode to C++/CX. This time the focus will be on the internals, the implementation strategy. And this will be the last time we address this small C++ extension for WinRT programming for a while. OK?

    As I said in an earlier reply, I think Herb's answer was thoughtful, precise, clear and easily understandable. I also feel he answered the exact question he was asked to answer. @PFYB, I respect your opinion and you are of course free to state your opinion here - we like this! -, but I'm beginning to suspect that there is no way to satisfy you. I mean, this is made clear by your reply to Herb's reply - as he did answer the question you posed. He just didn't provide the answer you're looking for. Is this fair?

    This is a very useful conversation. Let's keep it alive!

    C

  • CharlesCharles Welcome Change

    This conversation reminds of the scene in one of my favorite movies of all time, Thunderheart, where the elder tribal medicine man, Grandpa Regis, explains the vision he received from the spirits before "the FBI" came to town which accurately reflect the troubled childhood experiences of Ray LeVoy the young partially native American FBI agent seeking information from the wise man about a murder that took place on the reservation.

    After the elder spiritual leader finishes his story, Ray, shaken by the truth in the words just spoken to him, asks the tribal police chief who's translating Sioux to English for him, "does he have any information or not?".

    "He gave it to you."

    C

  • Thanks to everyone who has been commenting on this and also on the blog post I did.  It is clear to me that everyone is passionate about this and wants to see good things happen.

    I am a library guy at heart and I would love to see more of the C++11 features.  Stephan (STL) really wanted to see variadic templates.  It would have made his life easier.

    One thing that occurred to me is that we are in a somewhat difficult position here.  You guys aren't really asking us to justify why we did C++/CX, rather you are asking us to justify why we didn't do something else that didn't require language extensions.  You have even somewhat outlined what a solution could look like, which is to have a tool that can generate C++ code from metadata both for consumption and for what I would call pre-authoring.  The "pre-authoring" code might generate C++ base classes and other code you would use while authoring.  Then you need to generate metadata, which could come from the compiler itself or some form of post-processing tool.  The post-processing tool might also generate C++ code that gets built into the binary.

    I do agree that this approach is possible to do, although I believe that there are negatives to this approach.  We did consider several different possibilities during design and discarded them due to issues we ran into.  Herb and I have covered many of these.  Some of these issues were due to original design constraints (which some of you may disagree with as well) that we placed on ourselves such as wanting to avoid HRESULTs and lower level ABI types in the user-written code.  Some designs created too much burden on the developer in having to do the right thing and know too many internal details without clear support from the compiler.  Others would have caused undue performance overhead (such as creating something akin to CCWs and RCWs that .Net uses).  Many times, decisions came down to judgment, although we did prototype many aspects of C++/CX as we went along.  Sometimes, our design team was split down the middle and Herb would break the ties.  We also got feedback from others within the C++ team, other internal teams such as Windows, and some external partners.  We did get questions about our decisions and we were asked to reconsider certain decisions.  We took that feedback and would often spend a lot of time considering it.

    I don't claim that there is no design that could have solved all of these issues and done it without modifying C++.  But even if there truly isn't a good way to do this, to prove a negative thesis such as this would be near impossible.  We did look at approaches like this and based on our experience with MIDL, #import, and other tools, we simply didn't see a path down this road that we liked.  We have tried to condense a lot of discussion here and it is always hard to summarize some of this.  We have tried to show that the design of C++/CX does address what our goals were, and we have tried to point out issues with doing it other ways, but I don't see a way that I can prove to your satisfaction what you are asking.

    Here are some responses to specific questions/issues.  I've tried to read through everything, although I'm sure I'm missing some stuff.

    Interaction between standard C++ and C++/CX

    T^ arr[3];

    This should work.  We've opened a bug on it. 

    There was discussion about the fact that some standard C++ and C++/CX features don't play well together and you get errors when you try.  Often this is due to fundamental difference in the object models between C++ and WinRT.  The fact that I get compiler errors when I do things that are incompatible is better to me than silently compiling and getting some strange runtime behavior.  Where possible, we have tried to make C++/CX have fewer compatibility problems than C++/CLI, such as by allowing you to take the address of members and embedding standard C++ types into C++/CX ref classes.  That said, I want to make as much work as possible and suggestions or bugs in this area are very welcome. 

    Partial Classes

    There are other ways to do this and we've done them before, but there are some issues with those.  Emitting code directly into the user's code can be done, but it is usually non-trivial.  There is also emission of base classes/interfaces and data members that need to be constructed.  These require emitting code that is more intertwined with user code than just a simple region.

    File extension

    I like the idea of a different file extension that would imply the /ZW flag.  Calling it .cx seems pretty neat.  It does encourage the idea of separating the boundary/UI code from the core of the application, which I agree many people want to keep in standard C++ for portability.

    Optimizations

    There are two main places we are able to optimize.  The first is for arguments to functions.  In C++/CX, many parameters are hats (^).  A ^ implies that we are doing automatic reference counting.  For instance, if you have a ^ that is a member of struct and you assign to it, an AddRef will automatically be performed.  In some ways, this is similar to a shared_ptr.  However, when a ^ is passed as an argument to a function, we will not do an automatic AddRef/Release around it.  To accomplish something similar with a  shared_ptr, you would have the function take a "const shared_ptr<>&".  However, this is fundamentally different in that it means at the ABI that a pointer to the variable is actually passed. 

    We will also do this for String^ parameters.  String^ are different from other types in that there is no vtable for them and they may take one of two forms.  There is what is called a "fast-pass" mechanism where a "normal" C/C++ string can be passed to an API that takes a String^ (HSTRING at ABI) without copying the string.  We will automatically do this for string literals, wchar*, and all of the string classes we ship.  Other string classes can easily support this as well.  If the callee decides to hold onto the string it will be automatically copied if the string was fast-pass, but if it was not fast-pass then the reference count of the string can just be bumped.  So, both the caller and callee can do the optimal thing.

    The second opportunity for optimization occurs when calling methods of a class.  Keep in mind that methods of a class may actually be on different interfaces at the ABI.  If you have a WinRT class Foo, when you declare a Foo^, you are holding onto the default interface of Foo.  If you call a method of Foo that is on the non-default interface, the compiler will generate a QueryInterface call to get the interface and then call that method.  The optimization that is possible is when you make multiple calls to a non-default interface of a class (through a local variable that the compiler can prove can't change).  Someone programming in COM today or using the low-level WinRT ABI would likely see this and cache the QI call themselves, but the compiler can do this automatically for ^.

    ref new vs CreateInstance<T> vs new

    There were several things we didn't like about using "new T" where T is a ref class.  One is that the type of the expression is T^, but it is T* for non ref classes.  The second is that we wanted to leave the door open to the possibility of using "ref new" on a non-WinRT class and have that automatically create a reference-counted object.  You can override operator new, but "new T" of a ref class won't use it.

    Regarding something like CreateInstance<T>, you can definitely do this, but if you don't have "ref new", how do you implement CreateInstance<>?  Is CreateInstance<> magically understood by the compiler?  Does it do "new" under the covers?  If so, does that mean I can do "new T"?  What does that mean vs CreateInstance? 

  • GlenGlen

    @Charles

    You miss that you simply just roll right along without taking in any of what is being said.

    Here's what you missed me saying at least:

    What I said:

    1. A show idea is great.
    2. We aren't ready for a show yet.
    3. We don't have clear questions for Herb, but good ideas and potential.
    4. Of the views suggested, its not agreed yet which are Key nor the clarity of them.
    5. Give us more time. We need to argue and proove our case(s) with each other, to get clear questions for Herb.
    6. The process must happen so don't waste Herbs time AND so people don't stay angry at Herb unfairly.
    7. Herbs responses aren't and wont suffice and wont until he gets clearer questions and can give a clear answer.

    Look for my "rinse and repeat" starting point if that helps.

    Now go look and see how you responded. You just continued to solicit personal emails and continue with the show plan.

    Then go look at what happened after you continued doing that; you will see:

    1. Various different opinions continue about what Microsoft is doing that people aren't sold on yet.
    2. Great ideas, some definite possibilities, a few counter views, but no clear set of questions.
    3. People continue to call out, like @jalf, for a discussion thread and more back and forth time.
    4. Only real consensus: People aren't convinced "Microsoft has got this right or are doing what people want.".
    5. Herb answering and failing to suffice with his answers.
    6. Herb feeling let down that he spent time answering and it feeling wasted.

    In other words, that's exactly what I thought was going to happen and what I tried to avoid, and what you missed.

    Sorry that Herb feels he wasted his time. I can totally understand why he feels like that, but I also understand why people aren't happy with it.

    Charles, what I don't understand is how you manage to communicate in such a style that all of this missed you by or that it feels like it.

    I'll continue to work with the other guys. When it becomes clear, I'll try to articulate it. But as I said before, for myself, I'm particularly keen not to waste Herbs time until I see something clear as possible. Then I will check that with the other guys here first to test the agreement, then I really will expect an equally satisfying answer from Herb.

    For now, bottom line. I'm not sold on C++/CX is it is; I remain open to being convinced in either direction. The negative side is winning currently. That's as much as I can say directly to Herb right now.

    Everything else I have to say has to be aimed at yourself and other people to help me evolve that point of view so I exactly don't waste Herbs time, just my own and everybody elses until then.

    Thanks

  • GlenGlen

    @Jim

    Thanks for that, that appeared while I was posting my reply to charles. I'll take time to look at what you said but I have to run now. Thanks for your efforts. :)

  • CharlesCharles Welcome Change

    @Glen: Fair enough... I appreciate that this all has to bake for a while before the more insightful questions emerge, but it's certainly spot on to ask Microsoft why we did this in the first place, how it works and why we think the way it works is the right way. These topics are being addressed. It's great to see this level of discourse happening. Jim's post, like Herb's, presents the reasoning behind this stuff very clearly and accurately. These are great insights you're getting from the team. 

    Thanks Herb and Jim!!

    C

  • GarfieldGarfield

    @Jim -- first of all, thanks, it's a good reading. Second, as far as I understood from yours and Herb's answers, the consumption of C++ code by other languages was the most constraining and perplexing part that led to C++/CX design decisions. What I was thinking is that 99% of C++ developers aren't in the category of portable component writers. So I believe if that cross-language compatibility requirement is lifted then we could stay close-to-the-bone C++ design, making those 99% of C++ developers a lot more happy. Would it be possible in addition to C++/CX, which targets 1% of cross-language component developers, release a separate native C++ library that consumes WinRT, but limits exporting components for other C++ applications only.

  • @Garfield
    "we could stay close-to-the-bone C++ design, making those 99% of C++ developers a lot more happy"
    Are you kidding? Writing in ISO C++ sometimes can be pain in the * compared to managed languages. C++ is just too low level for GUI development to be comfortable with. The more features from managed languages we have - the better.
    I sincerely hope C++/CX will be standardized and consumed by ISO C++ to make all C++ developers' life easier.

  • @hsutter:

    PFYB responded in part: "I am deeply dissatisfied with the post from Herb [that answered exactly your question]. I am tired of answering the same old points ad infinitum [so evidently others have already given you the same answers to the same question]. I suspect Herb didn't read the thread. I suspect he won't. Such is the "discussion" we are having here."

    You didn't answer the question. You reiterated points which have already been discussed at length. You even borrowed several points from your previous post, which has been replied to at length as well. Now, it would be understandable if you disagreed with the replies, but you neither indicated any such disagreement, nor substantiated it. It is not like you put something forward, got an answer, then disagreed and put a counterpoint moving the discussion forward. No, what happened was that you put something forward, got an answer, then ignored that answer and put the same point forward once again. This is not a productive discussion.

    And, no, you didn't answer the question. You just started building your list of repeat points and various things that happened to cross your mind (like, "oh, right, we did this thing that saves a pair of AddRef / Releases, good, I will call that 'aggressive optimizations for refcounting'"), and after doing this for some time you decided you did enough and stopped. At no point did you actually answer the question.

    I did read the paper on design rationale for C++/CLI. So? If you want to carry a particular thought from there and apply it to C++/CX, do this. Just saying "hey, read that paper, you will understand why we did C++/CX" doesn't work.

    @Charles:

    I read Herb's reply and what I read was: Yes, we could have provided the model suggested in terms of some "reverse of #import"... But, this would have added a lot of complexity for everyone involved, including, and most importantly, end user C++ developers targetting Windows 8 Metro.

    Yes, we could have - good. But, this would have added a lot of complexity - please substantiate this. We fail to see how this would have added a lot of complexity. Herb's post isn't helpful, all of his points have been answered several times now and he didn't even say what he disagrees with, yet alone why. Same for the complexity for C++ developers.

    One more time, yes, C++/CX is easy, we argue that wrapping code both ways would produce an environment that would be equally easy to use.

    If this helps visualize things, here is example code in C++/CX:

    Window::Current->Content = ref new MainPage();
    Window::Current->Activate();

    Here is the code we propose for C++:

    Window::Current->Content = new MainPage();
    Window::Current->Activate();

    Is the proposed C++ code any more complex than C++/CX? Of course, not. The C++ code does not have the 'ref' keyword, everything else is the same. How this could be done? Wrappers.

    Feel free to post other example code, with events, delegates and whatever else. We will post what we propose this code converts to for C++. We can post fragments of wrappers and, in general, discuss the implementation, too. This is the entire point! This is what we are trying to start talking about! If there is something that can not be done using wrappers, let's take a look at this and see what we can do. But let's discover this first. Is it too much to ask that someone on the Visual C++ team spends a couple of hours checking if we can have all the benefits of C++/CX without altering the language? Is that not a worthy goal?? If you say you already did the work and determined that the approach we are proposing is a no-go, is it too much to ask you to demonstrate this with a code example??

    @JimSpringfield:

    One thing that occurred to me is that we are in a somewhat difficult position here. You guys aren't really asking us to justify why we did C++/CX, rather you are asking us to justify why we didn't do something else that didn't require language extensions. You have even somewhat outlined what a solution could look like, ...

    There is no need to second guess what we are asking. I, at least, while strongly believe that you could do everything without altering the language as proposed, am ready to talk about not only whether this is possible or not, but also whether it makes the most sense to do it this way or not. The questions we are asking are honest: ( a ) could you do the C++/CX in C++, eg, in the way we propose, ( b ) if not, why, ( c ) if yes, why didn't you do it this way. The problem with the discussion is that the responses we get from, say, Herb, do not answer ( a ) and just muddle around from time to time throwing out points like "oh, yes, we'd also have to map HRESULTs to exceptions" and pseudo-points like "oh, but what the debugging experience would be? I suspect it would be worse". This is not productive.

    What kind of answers would we be satisfied with? Easy. No second guessing necessary here either. To ( a ) we would accept "yes, we could do everything there is in C++/CX using C++ wrapping code as you suggest" or, say, "no, wrapping code wouldn't work, here is why: <explanation why>". This covers ( b ), too. I suspect it is ( c ) that you have problems with. It is indeed difficult to answer why you didn't do everything in C++ if it was possible and maybe even easier than doing C++/CX. I can't help you here, unfortunately, but I would point out that the next version of VS is still not even in the beta and that there will be a version of VS after that.

    ... which is to have a tool that can generate C++ code from metadata both for consumption and ... I do agree that this approach is possible to do, although I believe that there are negatives to this approach. We did consider several different possibilities during design and discarded them due to issues we ran into. Herb and I have covered many of these.

    At this point, Jim, I want to thank you for actually reading what we have been saying and getting what exactly we are proposing for consuming WinRT from C++. You are the only guy from Microsoft who did that. Thank you.

    You are saying that this approach has negatives. Of course, every approach has both positives and negatives, that's a given. The question is which approach is better on balance. If you think the approach with wrappers is worse than the one you took with C++/CX, we would appreciate your thoughts as to why. The huge benefit of the approach with wrappers is that it allows using C++ without altering the language. This is the entire reason we suggested it in the first place. It seems to us that in all key areas, wrappers could work just as well as C++/CX, and in some areas, they would work better than C++/CX. The benefits from using C++/CX over C++ (like the "aggressive optimization of refcounts") on the other hand seem completely minor. Consequently, it seems that on balance, the approach with wrappers is a clear winner. If you disagree with that, we would appreciate yours saying why.

    As a side note, if you don't disagree, but you think that the ship with C++/CX has already sailed, that's fine too, but please say it how it is.

  • @JimSpringfield:

    I thought I would point out that every single optimization you describe you did for C++/CX would have been possible if you generated wrapper code:

    There are two main places we are able to optimize.  The first is for arguments to functions.  In C++/CX, many parameters are hats (^).  A ^ implies that we are doing automatic reference counting.  For instance, if you have a ^ that is a member of struct and you assign to it, an AddRef will automatically be performed.  In some ways, this is similar to a shared_ptr.  However, when a ^ is passed as an argument to a function, we will not do an automatic AddRef/Release around it.  To accomplish something similar with a  shared_ptr, you would have the function take a "const shared_ptr<>&".  However, this is fundamentally different in that it means at the ABI that a pointer to the variable is actually passed.

    With wrapper classes, wrapper code would have taken "const shared_ptr<>&" or const reference to a different type of smart pointer, then it would have taken the actual value of the smart pointer, without doing an AddRef, make the underlying WinRT (COM) call, then returned the result without doing a Release. Done.

    We will also do this for String^ parameters.  String^ are different from other types in that there is no vtable for them and they may take one of two forms.  There is what is called a "fast-pass" mechanism where a "normal" C/C++ string can be passed to an API that takes a String^ (HSTRING at ABI) without copying the string.  We will automatically do this for string literals, wchar*, and all of the string classes we ship.  Other string classes can easily support this as well.  If the callee decides to hold onto the string it will be automatically copied if the string was fast-pass, but if it was not fast-pass then the reference count of the string can just be bumped.  So, both the caller and callee can do the optimal thing.

    A naive approach:

    The wrapper code takes const std::wstring&. It extracts a const wchar_t* pointer from the wstring and passes that to WinRT without wrapping it into HSTRING. Returned HSTRINGs are converted to wstring.

    A more involved approach, if the team thinks it is worth it to save on conversions from const wchar_t* (eg, literals) and HSTRING (return values from WinRT) to wstring:

    The wrapper code implements methods with string arguments and or return values as more than one method with arguments and return values being either wstring or a library class that wraps all of wstring / HSTRING / const wchar_t*. There is no need to try all combinations, two combinations are all we need: either all types are wstring, or all types are the uber-wrapper class. The implementation code for the method that uses the uber-wrapper class uses the logic you have in C++/CX.

    There are alternative approaches as well. Done.

    The second opportunity for optimization occurs when calling methods of a class.  Keep in mind that methods of a class may actually be on different interfaces at the ABI.  If you have a WinRT class Foo, when you declare a Foo^, you are holding onto the default interface of Foo.  If you call a method of Foo that is on the non-default interface, the compiler will generate a QueryInterface call to get the interface and then call that method.  The optimization that is possible is when you make multiple calls to a non-default interface of a class (through a local variable that the compiler can prove can't change).  Someone programming in COM today or using the low-level WinRT ABI would likely see this and cache the QI call themselves, but the compiler can do this automatically for ^.

    The wrapper code for a WinRT class can, of course, cache all interfaces it ever calls. A very simple approach which might be enough for the vast majority of cases would be to simply QueryInterface for all supported interfaces in the constructor. If this ends up wasting too much time for classes implementing multiple interfaces (multiple calls to QueryInterface in constructor mean multiple interlocked calls, same for destructor), one can always cache queried interfaces on demand. There are lock-free techniques for this.

    Alternatively, if any of the above is not acceptable, the wrapper code can always expose classes wrapping non-default interfaces. Anyone who finds out that the code spends too much time doing AddRef / Release on the arguments can request an instance of such a class and do the calls through that instance.

    Now, let's see an optimization you would be able to do if you did everything in C++ instead of C++/CX:

    Suppose you have a class you are exposing to WinRT. If you are also calling its methods in some of your other code in the same module, the compiler would be able to inline these calls.

    Unlike saving a pair of calls to AddRef and Release here and there, having the ability to inline code actually matters. There are many cases where a developer has to split his code into several methods, as dictated by a design (witness property getters, for example), there is a lot of performance to be gained by putting these chunks of code together at runtime, and only the compiler can do this. The exact benefits depend on the design, of course, on average they are significant, and sometimes they are simply huge.

    Are you doing the inlining of WinRT code in the same module right now? Across different compilation units? I don't think so. If you went with straight ISO C++ you would have gotten this for free.

  • DennisDennis

    @hsutter

    You say:

    -------
    @PFYB responded in part: "I am deeply dissatisfied with the post from Herb [that answered exactly your question]. I am tired of answering the same old points ad infinitum [so evidently others have already given you the same answers to the same question]. I suspect Herb didn't read the thread. I suspect he won't. Such is the "discussion" we are having here."

    Wow.

    You're welcome. Sorry that I can't be helpful.
    -------

    You say you have answered the question by PFYB - you haven't.

  • DennisDennis

    @Charles

    "Do an experiment, if you will. Take an existing physics library or math library or image processing library writtten in C++. Create a Windows 8 Metro C++ app. Create a shared module out of it. Do this with C++/CX at the boundary (so, the insides are written in C++, the skin on the outside is written in C++/CX). Now, do this same thing (the boundary, the shareable skin) in WRL. You tell us which is harder, which is more insane, which is too complex."

    This is missing the point. See the numerous posts by PFYB, Tomas and others. See the last point by JimSpringfield, if you will. The comparison between C++/CX and WRL is missing the point. The real comparison is between C++/CX and C++ wrapper classes generated two ways. Does this get through?

    Later in your post you get a bit annoyed and say that Herb Sutter explained why the approach the team have taken with C++/CX is better than the approach with C++ wrapper classes. He didn't. He didn't explain this. He didn't explain why wrapper classes would be inferior. Take a look at his list of points. Does the first point explain why wrapper classes are worse than C++/CX? No, it is irrelevant to the question. Does the second? No, it is irrelevant to the question. The first five points are all irrelevant, and the last three are... well, can I just say "questionable" to be polite. Read them and you will see for yourself, you really want to say that one of the major reasons - one of only three reasons as the list provided by Herb Sutter suggests - to prefer C++/CX to C++ is better performance? Really? We aren't idiots.

    I have been watching this thread with interest. It contains a lot of very good points. I know I now understand a lot better what WinRT and C++/CX are. I also understand that I should stay away from C++/CX and that I should likely start looking for a new compiler besides Visual C++.

  • ISO 14882ISO 14882

    To add to what PFYB is talking about - please have a look how the new CORBA mapping to C++ is going to be done (http://www.orbzone.org/forum/70). It's exactly the same kind of stuff - mapping of a foreign object model to C++. But there's no ^, Platform::String or IVector - only std::shared_ptr, std::wstring and std::array/std::vector. They're getting it right, you MS are not.

  • ISO 14882ISO 14882

    @JimSpringfield

    "Partial Classes
    There are other ways to do this and we've done them before, but there are some issues with those."

    Could you please explain why the most straightforward way of doing it in ISO C++ wouldn't work? What relevant functionality partial classes offer that this method does not:

    // Form1.designer.h - edited by the designer tool
    Button button;
    // etc.

    // Form1.h - edited by the user
    class Form1 : public Form
    {
    // user's code
    private:
    #include "Form1.designer.h"
    };

  • WarrenWarren

    @JimSpringfield

    Thanks for the post.

    First, since you are saying that you are going to fix a compilation error on 'T^ arr[3]', you could as well also fix 'T^* arr = new T^[3];'. This does not compile either, likely for the same reason.

    Second, maybe you can answer a question on borders asked by Dennis higher in the thread (thanks!):

    Do you have any examples of large applications that are now written in C++ and that are going to be moved to WinRT? If using WinRT (and C++/CX) on the border is as simple as you imply, there should be such applications.

    I and others are sceptical on the whole borders issue. It didn't exactly work out with C++/CLI to say the least.

    Thanks again.


    @hsutter

    I am sorry, but:

    @PFYB: "I suspect Herb didn't read the thread. I suspect he won't. Such is the "discussion" we are having here."

    @hsutter: "Note that this is now a 32,000-word thread. That's half the word count of Exceptional C++."

    Herb, can't you see that you are making PFYB's point? You don't deny that you didn't read the thread but you make it seem like you do deny it. Maybe this is going to be a surprise for you, but you do the same with the real points regarding C++/CX. Reread the thread. We really expect more from you.

  • @Charles:

    This isn't really about you using multiple languages yourself in a single project - though it certainly could be the case that you would want to, say, build a UI layer in HTML5 (HTML + CSS + JS) and write the core application logic/algorithms in C++ or use XAML for the UI layer, etc... It's certainly possible, though somewhat far-fetched, that you would want to write an app that uses C#, JS and C++, but, implicitly, you probably will be doing just this: You will be consuming components across language boundaries (they could have been authored in C++, JS or C#...), many of which are not written by you... That's a key point. 

    I am talking about what I know, that is, creating consumer apps (in C++, although I've tried in C#, but I failed).

    You are talking about 2 different scenarios where using multiple languages might be usefull:

    - using a 3rd party library built in C# or C++ or JS. Well if I write C++ native code, I will certainly not hamper my app performance by using a 3rd party C# or JS library. The C# library would have to initialize a CLR, and that would consume a lot of resources. It doesn't make sense. And If I use a C++ 3rd party library, I would better use a ISO C or C++ API than a C++/CX API. I bet the 3rd party vendor has published his C++ library as a native C or C++ interface before he adds a C++/CX layer.

    - building a user interface in HTML5 or XAML/C#. Well, I can use XAML interface in C++/CX right? Also, we've been trying for 4-5 years to create hybrid applications with WPF UI and C++ code. It has been proven it is not possible. The only hybrid app I know is Visual Studio 10, but Microsoft had to modify WPF to make it work, and invested a lot of energy in this project. Why would hybrid apps make sense now?

    Really, I'm not interested in being able to use other language components.

    I think C# or JS devs are interested in using C++ library. This makes sense. This also requires the vendor to write a C++/CX layer on top of his library. But C# programmers can already use C/C++ lib without C++/CX. Of course a C++/CX interface is more C# friendly than a native ISO C/C++ interface. 

    Your point is OK with C#.

    Do an experiment, if you will. Take an existing physics library or math library or image processing library writtten in C++. Create a Windows 8 Metro C++ app. Create a shared module out of it. Do this with C++/CX at the boundary (so, the insides are written in C++, the skin on the outside is written in C++/CX). Now, do this same thing (the boundary, the shareable skin) in WRL. You tell us which is harder, which is more insane, which is too complex. 

    I've already done this kind of thing. I do agree with you: C++/CX is far more usable than WRL. But ... (you know)

    I don't know how to create a Win8 app with "C++/CX at its boundary". In all C++ code for Win8 I've seen/written yet, there is no such thing as "C++/CX at its boundary" as the "boundary" tends to be 50-90% of the code. But, as I already said, I have not seen a real Win8-Metro C++ app source code, it may be different.

    Once again, things are really different in C#.

    This hybrid application environment that WinRT supports seems to me to be the most compelling thing about it. As you learned in the BUILD sessions on Windows 8 Metro Style Applications and WinRT, there are compelling user-centric features provided by the underlying system that your application can take advantage of for free, but only if you play by WinRT's rules (again... WinRT defines the model, not the languages used to program WinRT apps...). 

    Hybrid application environment sounds terrible for me... I've spent so much time trying to write managed interfaces to native programs... I don't want to do that again.

    OK we need to play WinRT rules if we want to write Metro apps. Make sense. WinRT defines the model not the language, but this model is close to (designed for?) C#, not C++ (yet).

    I guess many small apps will be written in C# for WinRT. The kind of app you see on iPhone or Android. They are not expensive to develop. I wouldn't write this kind of app for WinRT in C++.

    For larger customer apps, C# is too weak. I don't know about C++ and WinRT. Not sure I want to spend a lot of time on this.

  • jalfjalf

    @Jim Springfield: thanks for the answers.

    > Regarding something like CreateInstance<T>, you can definitely do this, but if you don't have "ref new", how do you implement CreateInstance<>?

    That's an implementation default. Perhaps the compiler generates and links in explicitly instantiated specializations of this function for every WRT class used, so that only the declaration needs to be visible to users. Then the actual definition is hidden from us, and it can use whatever magic it likes. And then I can call CreateInstance<Foo>, and the linker will find the instantiation of this specialization. Or it could be a simple forwarding function which calls a non-template CreateInstance(classId) instead. Or something else. Point is, it could be standard C++ syntax which behaved like standard C++, and then it would minimize the weird/ambiguous/unspecified/unintuitive/nonstandard cases where C++ and C++/CX syntax intersect.

    You're right, we're putting you in an impossible position, and there's no perfect solution.
    But I, personally, would have liked to see a more minimal and less intrusive solution, one which introduced less proprietary syntax, and thus made it easier to avoid "polluting" my actual C++ code first, and then perhaps, a year or two down the line, a set of more intrusive language extensions like you have now.

    Of course, now C++/CX is pretty much set in stone, and it's pointless to argue about what *should* have been done. But I hope to see future improvements to C++/CX, which:
    - make it possible to use it in a less intrusive manner, which keeps some kind of clear separation between C++ code and C++/CX, and
    - (at least optionally) provides ISO C++ alternatives to some of the C++/CX syntax (say, a simple smart pointer to replace the hat, and perhaps as I outlined above, an ISO C++ (template) function as an alternative to ref new)

    I feel that (and correct me if I'm wrong), this whole "C++/CX at the boundary only" thing has never really been put to the test. I get the impression that all the components written by Microsoft so far have been in C++/CX throughout. I get the feeling that you felt that the "boundary only" thing didn't apply to your internally developed components, and so it was never really tested how well C++/CX actually lives up to this ideal, and you ended up with a set of intrusive language extensions that are very hard to restrict to the boundary.

  • ISO 14882ISO 14882

    @Jim Springfield

    "Regarding something like CreateInstance<T>, you can definitely do this, but if you don't have "ref new", how do you implement CreateInstance<>?"

    I guess the same way you implemented instance creation in WRL?

  • RonRon

    @jalf:

    > Of course, now C++/CX is pretty much set in stone, and it's pointless to argue about what *should* have been done.

    Actually, there is a point. If Jim and other Microsoft people see that they really could do everything they wanted without harming the language, maybe they won't be so quick to harm it again three or so years down the line when the current crop of technologies on the Microsoft stack goes out of fashion. I am dead serious.

  • jalfjalf

    @Ron: that's true. But ultimately, I still think the best way to achieve that is to discuss what route C++/CX should take *in the future*. Because then that can act as a starting point the next time they decide they need a new C++ to complement the 4 they've already got.

    @Charles: watching the video, you keep emphasizing that "ref new and hat is not a big deal". Please, think about that for a moment:

    you're redefining how we create objects, and how we refer to existing objects. What changes could *possibly* be bigger? I seriously cannot imagine a single change that'd have a larger scope. And that's why C++/CX makes me uncomfortable: those two operations, referencing an existing object (whether we do this through a reference, a pointer or a hat), and creating new objects are really ubiquitous operations: it's impossible to write *anything* meaningful in C++ without touching those operations. But now suddenly we've got a bucket of types for which these operations have to be written differently. We have pointers which aren't pointers, and will, I'm assuming, mess up any code which relies on, for example, std::is_pointer<T>, or which will break if I try to allocate or copy them in the usual way. These are unavoidable changes, and all the code I write now has to consider "am I getting a pointer to a C++ class, or a ref-counted pseudo-pointer to a WinRT class?"

    Yes, ref new and hat is a big deal. It may turn out that adding these extensions was a good idea, but let's not pretend that it's not a big deal. Whatever else it is, whether it's good or bad, it most definitely is a big deal.

  • GlenGlen

    @everyone: lots of great opinions, nice to see.

    @jalf "...it's pointless to argue about what *should* have been done..."

    Not at all:

    * We might be able to Change v1. But ok, lets assume not for argument sake.

    Even if we can't change V1:

    * We are "fit for purpose" testing it without blowing a big project on it. This is of real value.

    * If we can proove its fit for purpose already, great. Now we can dive in with confidence, sooner and with reasons for our selling case to higher ups and customers.

    * If it isn't quite fit, we can help others know where the pitfalls are. This is already working.

    * If it's really not fit for purpose at all, we can why, and v2 will arrive quicker.

    * If we have the right fit defined and MS ignore it, we know who are friends are.

    * If MS wont build it, MS's competitors will, we have the spec. Or we can build it outselves with Clang.

    No more hostage to fortune.

    This things a) value proposition needs to be understood and prooven, b) it needs to be understood what's wrong with it or not as defined by MS so far, then how do you do it better or right if its wrong. Getting it all out now for V1 or V2 is worth it for me, for all these reasons and the hard reasons above.

    Beyond that, I still hope people will also focus on, "the right language extensions" not just, "none". None is best iff it's right. As long as people can keep proving none is better, that's great though.

    I'll be posting more tomorrow when I have more time. But thanks for your comments, keep them coming, I'm reading what you have to say with interest.

    @Jim, thanks for your reply. The tone and content of your resposne was excellent, I really feel you were listening.

  • @Glen you're saying:

    "Beyond that, I still hope people will also focus on, "the right language extensions" not just, "none". None is best iff it's right. As long as people can keep proving none is better, that's great though."

    In my opinion language extensions have the right to exist iff there isn't an easy or possible way to achieve goals with already existing features. As we proved here this isn't the case with CX. Everything what CX does can be done as easily (and in most cases even easier) with C++. No need for extensions in this case.

  • DennisDennis

    "In my opinion language extensions have right to be iff there isn't an easy or possible way to achieve goals with already existing features. As we proved here this isn't the case with CX. Everything what CX does can be done with C++. No need for extensions in this case."

    Hear, hear.

    If the Visual C++ team is serious about staying true to the standards, they should drop C++/CX and allow us to consume WinRT via C++ wrappers, as suggested. They will be able to reuse much of the work they had to do for C++/CX and there is still time since, as others mentioned, VS vNext is not even in the beta state.

    If the team won't do this, we should ignore C++/CX for several reasons:

    First, if you invest into C++/CX you will have it all over your code. The "just on borders" argument is a lie. Try doing "just on borders" with your application by converting the way it interacts with the system from Win32 to .NET, using C++/CLI. See how far the border will go (everywhere). It is going to be the same with WinRT and C++/CX. Do you want to make most of your code non-compliant?

    Second, C++/CX is a half-baked throw-away technology. It is so brittle and artificial, it will likely be replaced by another technology or simply abandoned. Compared to C++/CX, .NET and Silverlight look solid as rocks and where these technologies are now? If you choose to use C++/CX, you will likely find yourself having to redo that code all over again in a couple of years. Save yourself the hassle and just do whatever you want to do with Metro UI using HTML5 and Javascript.

    Third, ignoring C++/CX sends a message. This continuous stream of Microsoft extensions to C++ should just stop. I don't want to have to deal with one more language extension come Windows 9. I don't want to hear Herb Sutter explain how the new extension makes a lot of sense because it makes it all look pretty in the debugger. Enough.

  • I completely agree, Dennis.

    By the way, I have a question for Herb Sutter.

    Herb, upon joining Microsoft back in 2002 you gave this interview:

    http://www.codeproject.com/KB/interviews/herbsutter3032002.aspx

    You said many interesting things. In particular, you said that you "will be pushing for language extensions in Microsoft's C++ even before the product is fully compliant to today's standard". That said, you caveated this as follows:

    "Don't get me wrong, I'm certainly not pushing for a lot of extensions, and certainly not anything where there isn't already a clear need and some community agreement. And when I propose those features within Microsoft, it will be after I've already talked with the world's top experts about how important they are and how they should be specified; I hate half-baked homebrew misfeatures and that's certainly not what I'm after here. I'm pushing for a handful of carefully chosen and carefully implemented extensions that the community is clamoring for, and which are not proprietary but rather the opposite: things we already know are certain or likely to come in C++0x and which we hope all compiler vendors will provide too. A standards committee can sometimes be inventive, but mostly it's supposed to standardize existing practice; I want to help Microsoft help the standard by providing just that "existing practice in the field" for these key upcoming features. Indeed, by trying to carefully wield Microsoft's product as a leader in this way I personally hope to help move the whole community forward on all compilers and platforms, as other products are encouraged to implement them too, which will benefit everybody no matter whose tools they're using."

    I have a hard time reconciling the above with what happened with C++/CX. Did you significantly change your stance on extensions since the time you gave the interview? If not:

    1. Isn't a third extension (on top of countless things marked as "Microsoft-specific" which we take as a given) in 10 years "a lot"?
    2. Was there really "a clear need" for C++/CX given that a strict C++ alternative as suggested in this thread was possible as well (if you disagree it was possible, I'd appreciate knowing why, but I have already asked about that a number of times to no avail, so if you disagree but won't say why, just skip the question)?
    3. Was there "some community agreement" around C++/CX?
    4. Is C++/CX one of the things the community "has been clamoring for"?
    5. Is C++/CX something that is "not proprietary but rather the opposite: thing we already know is certain or likely to come" in the next version of the C++ standard and which you "hope all compiler vendors will provide too"?
    6. Are you encouraging other vendors to implement C++/CX "to the benefit of everybody no matter whose tools they're using"?

    These are serious questions. What changed between 2002 and 2010 or whenever you started working on C++/CX? Why? Answers to these questions will help us understand what you are going to do with C++ in the future. I am not too optimistic, but, well, explain yourself. We'll listen.

    Thank you.

  • MortMort

    PFYB, indeed I'd very much like to know how Herb Sutter answers your questions.

    "half-baked homebrew misfeatures"? This sounds exactly like C++/CX to me. "half-baked" = numerous problems in integration with other language features, as shown higher in the thread. "homebrew" = Microsoft-only invention, nobody saw it before //BUILD, nobody got a chance to comment. "misfeatures" = unnecessary, can be replaced with standard-compliant C++, as discussed in the thread. Yes, C++/CX is all that, a "half-baked homebrew misfeature" of the kind Herb Sutter hated back in 2002.

  • I've been thinking about this over the weekend. (Yes, I did read parts the thread last week and since then, though it really is too long to read in detail.) When two people express themselves and try to listen, and both still feel unheard, it's usually because of a fundamental disconnect. In this case, I suspect it's a difference about design goals.

    Before I go further, let me sanity-check something: Do we agree that the route of "extending TLB #import" leads to a full ATL + MIDL like approach?

    This seems to be a key point since early in the thread:

    • @Glen actually complained of us doing IDL in the past. Amid a list of our technologies: "... Then we had COM. Object based, but hardly useable and hardly C++, just IDL and a vtable. In reality, it was even less friendly than C. ... Where in that great mass of development is a simple ISO C++ API? I don't see one! Now I realise I never had one!!"
    • @C64 asked: "What would be an ISO C++ alternative to C++/CX? Would it require using preprocessor macros? Would it require a separate compiler (kind of like MIDL) for metadata or other platform specific stuff? I'm not sure this would be better than a platform-specific language extension like C++/CX."
    • @PFYB replied: "Yes, macros, base classes, as well as tools (or new logic in the existing tools) to generate and use metadata."

    Later, when I replied saying in part that this path leads to growing a full MIDL language/compiler and toolchain model" (which we completely agree is feasible; we've done it in the past), two of the responses were:

     

    • @Dennis wrote: "You are willing to do a full-blown compiler and toolchain for C++/CX, but not for C++? How is parsing C++ code and generating other C++ code significantly more difficult than parsing C++ code and generating metadata?"
    • @PFYB wrote: "We suggest you generate wrapper code for exposing C++ classes to WinRT in the compiler, using a logic similar to the one you employ for generating metadata out of ref classes. Alternatively, move that logic into a separate tool. Before you say so, yes, we realize this logic is going to be different than the one you are using for ref classes right now."

    So I'll assume (please correct me if I'm wrong) that we agree that extending the #import model for the consumption side means that the authoring side would employ something like a MIDL language and compiler/toolchain -- so that programmers could specify the additional information that is needed for metadata -- plus a supporting structure of macros, base classes, and/or ATL-like smart pointers. Correct?

    If that's the question, let me do my best to shed light on it...

    At the outset of the project, my team was asked by our management to take as primary design requirements that we find a programming model that should:

    R1. Enable full power and control, including both consumption and authoring. It's C++'s turf to leave no room for a language lower than C++ to get at the underlying platform, and we wanted that to be true also for WinRT. There should never be a reason to use another language to be able to control or express WinRT-like things. I think(?) this is noncontroversial on this thread (correct me if I'm wrong).

    R2. Be as simple and elegant as possible for the developer. In particular, the model should minimize both the quantity of the code the user has to write and the complexity of the build system he has to deal with, comparable to the other WinRT languages. The main reasons for this goal were:

    • To minimize the amount of non-ISO C++ code the user has to write. Whether via language extensions or MIDL extensions, the user has to express information to author extra information about a type, this is inherently nonportable WinRT-specific code, and we wanted the user to have to write as little of it as possible, and as easily and quickly as possible, to spend as little time as possible on that necessarily evil on the wrapper around his portable ISO C++ code.
    • To not create a disincentive to use (V)C++ on WinRT. When writing most of the program code in C++ is appropriate, we don't want "but I want to also use WinRT" to create an incentive to use a different Microsoft language/compiler instead of VC++. It would be a disaster if we now had all this wonderful native (not-managed) WinRT environment but created an incentive to use it from a non-native language (i.e., not C++) for usability reasons alone. As one litmus test, if in side-by-side WinRT examples on MSDN the VC++ example is routinely twice the code of the C# example, we have a serious problem of people using the C# compiler instead, and often not just for the boundary code -- it would actively hurt ISO C++ use on the platform by creating an incentive to use another language compiler instead. We felt it's essential not to dilute the message that "modern [ISO] C++ code is as clean and safe as code written in other modern languages" by adding things like "except when you use WinRT or want to write a modern Metro app or do other modern things with it."

    I suspect that the tension in this thread is around R2, because that goal/constraint is in conflict with an ATL + MIDL like approach. As a simple example that doesn't even use properties/delegate/events, consider:

    ref class Screen {
    public:
        int DrawLine( Point x, Point y );
    };

    Screen s;
    s.DrawLine( Point(10,40), Point(20,50) );

    In this admittedly simple authoring example, the only syntax delta from ISO C++ is "ref" and the code is all in one place; no extra tool is required, and the user just wrote a few more letters and moved on.

    Two questions:

    A. What is the minimal code syntax and build steps it would it take to express this in a MIDL-style approach, and across how many source/intermediate files? What's the best we could do in that kind of alternative approach?

    B. How do you feel about these two goals?

    1. Minimize the actual amount of non-portable non-ISO C++ code/tools developers have to write/use to use WinRT.
    2. Make the code in the .cpp file itself appear to be using a C++ library, even though it actually is not (it is generated from Windows-specific language/extensions that are just located in a different non-.cpp file).

    Both goals are pro-ISO C++ statements, but they are different and actually in conflict -- at least, I don't know of a way to achieve both simultaneously, and we tried.

    So it sounds like perhaps the fundamental tension is that this time we aimed for answer B1 but some other people would prefer answer B2 (which we aimed for in the past with ATL + MIDL). I think either choice will unfortunately disappoint some subset of developers. We have lots of experience shipping B2 and know its weaknesses and the reasons why some customers have kept telling us they don't like it; for example, people have complained equally that that's not ISO C++ either (I agree; I don't think either C++/CX style extensions or MIDL extensions/tools ends up being any more "ISO C++," and I think there's feedback about that even on this thread such as @Glen's and @C64's comments I quoted above).

    Either way, it's still all nonportable proprietary extensions that are not ISO C++, just in different places and styles, and so I have sympathy for prioritizing the B1 goal of at least minimizing the quantity of it (as a subgoal of requirement R2 above). The primary reason we couldn't convince ourselves to do down the B2 path again was because every time we generated side-by-side WinRT-using examples we found it made the user's code more verbose even in the .cpp file, and added more complexity and extensions in the .idl file and compiler that would be needed, and therefore (we felt) failed to achieve R2 because it created a disincentive against using VC++ for WinRT projects which includes a disincentive against using C++ for even the non-boundary code.

    There are other design goals and constraints we already mentioned, such as supporting properties/delegates/events which begs for language support and supporting tools like debuggers and design tools well, but even those are secondary to these two fundamental requirements R1 and R2 above.

    We're really trying to answer the question, part of which is to find the fundamental underlying root causes motivating our difference in preference. I think (hope?) that identifying R2 along with highlighting the tension between B1 and B2 maybe at least some progress toward that. Whether or not we all agree that R2 is important, or which of B1 vs. B2 should be prioritized, is this at least helpful as a step toward understanding the root of our differences in what we all variously would prefer the design to be?
  • @Garfield

    I wouldn't say that the issue is strictly about exposing C++ code to other languagues.  It is really about exposing code through WinRT (which does allow other languages to use it).  The primary authoring scenarios to me are around using DirectUI (XAML).  It has been a long time since Microsoft provided a good way for native developers to do UI.

    @PFYB

    "The questions we are asking are honest: ( a ) could you do the C++/CX in C++, eg, in the way we propose, ( b ) if not, why, ( c ) if yes, why didn't you do it this way."

    I think I have answered these.

    a) Yes
    b) n/a
    c) Because we didn't see this approach as the best solution for our users.  We've tried to cover many of the issues that pushed us to C++/CX and I can understand if you disagree with some of them.

    "If you think the approach with wrappers is worse than the one you took with C++/CX, we would appreciate your thoughts as to why."

    I think we have been trying to explain this.  I often see one of two responses (not just from you PFYB): "that issue isn't important to me" or "you can get close to that with a wrapper".  I can't really argue against what anyone else thinks is important, but we have tried to state our assumptions and the goals we were trying to achieve.  The fundamental issue seems to boil down to how good of a solution could be delivered with some wrapper mechanism vs that of language extensions.  Based on responses, I believe some of you would be willing to accept a more convoluted solution in exchange for it not being based on language extensions. (Note: I will admit that it is not a given that this solution would necessarily be more convoluted, although it is my belief that it would be.)

    Specifics on optimization

    What you suggest with parameters is in fact what usually happens today in COM.  Interface pointers are passed as bare pointers to functions, but are held onto using a smart pointer.  However, I have seen a lot of code where people pass smart pointers by value.  Even passing a const& is sub-optimal as you are really passing a pointer to the pointer.  This type of system can work, but we really wanted something simpler.  We actually spent a lot of time trying to decide whether we should expose raw, but high-level, interface pointers and eventually decided against it in order to keep the model as simple as possible.

    Regarding modules, we do NOT go through WinRT machinery when accessing a locally defined (within a binary) ref class.  So, we can inline code and take advantage of other compiler optimizations.

    @ISO

    I will take a look at what you say CORBA is doing.  Sounds interesting.

    Regarding partial classes, I explained that there is often more than just putting additional methods and data into a class.  Often, you need to modify the set of bases for the class.  Sometimes, you also need to inject code into constructors/destructors or other functions, although usually that can be worked around.  Also, doing a #include inside of a class would make it really hard on the browsing tools within the IDE.  You can take a look at some of my posts on Intellisense/browsing for more background.

    Regarding CreateInstance and WRL.  WRL doesn't use ^ and creates objects similarly to how ATL did it.  "Ref new" returns a ^, not a *.  If you get rid of hats (or similarly marked up pointers), then you don't need it.

    @Warren

    Yes, "new T^[3]" should also work.

    There will be large applications converted to run in WinRT.  I can't provide more details than that, sorry.

    Regarding C++/CLI, I totally get your point.  We were never a first class .Net language.  Winforms support wasn't great, and WPF never happened.  I do believe this is different, however.  This is going to be the ONE way to access Windows moving forward and everyone is committed to having native languages be a part of that.  We aren't an afterthought.  We are part of it.  Also, when Windows creates new APIs, they commit to them for a long time.

    @pierremf

    It is hard to make general characterizations about what percentage of an app is boundary or not.  There are many large applications that run across different operating systems where a very large percentage of the app is written in portable C++ and the UI is written to target a particular OS.  (Note: some people use Qt or other frameworks to make this even easier.)  There are also some small apps that do this.  Usually, partitioning an app like this is done for portability.

    @jalf

    Creating a smart pointer and a CreateInstance<> template would be pretty easy, but it would be harder to make them work with the existing machinery.  You would still need to use ^ for methods.  You could create a typedef to use for parameters (e.g. IFooParam).  I don't see us providing this, however.

    There is lots of code that is WinRT at the boundary.  Windows itself is doing this.  Because C++/CX wasn't available at the start of the project, most Windows code is implemented using WRL, but some stuff is being done in C++/CX and we expect more to come.

    @KMNY

    "In my opinion language extensions have the right to exist iff there isn't an easy or possible way to achieve goals with already existing features. As we proved here this isn't the case with CX. Everything what CX does can be done as easily (and in most cases even easier) with C++. No need for extensions in this case."

    This really gets to the heart of this discussion.  As you say, this is your opinion (and of some others here).  I agree that if there isn't an easy way, language extensions may not be called for.  However, I still don't believe there is an easy way.

    @Dennis

    We believe C++/CX provides value and we are committed to it, but customers can always choose not to use it.  We want to make it the best we can, but at some point the marketplace is the true decider.

    Summary

    We are committed to C++/CX and I still firmly believe it is the right approach.  Even though we have not released Beta yet, there is no chance that we will fundamentally change directions at this time.  (Someone asked this, but I can't put my finger on the name.)  However, we are still very interested in feedback on bugs and issues that people are finding with C++/CX.  Places where there are impedance mismatch issues with standard C++ are also good to know.  We have tried to reduce these compared with C++/CLI, but there are obviously more.

  • Interesting; I'm glad to see how well that interview has held up over the course of a decade where my own understanding of Microsoft products/platform/ecosystem, as well as the course of the industry through through a major transformation or two, has changed a lot. I still agree with pretty much everything I said, including the need for further conformance to the new C++ standard now that it has stabilized and was published last month.

    @PFYB asked:

    1. Isn't a third extension (on top of countless things marked as "Microsoft-specific" which we take as a given) in 10 years "a lot"?
    2. Was there really "a clear need" for C++/CX given that a strict C++ alternative as suggested in this thread was possible as well (if you disagree it was possible, I'd appreciate knowing why, but I have already asked about that a number of times to no avail, so if you disagree but won't say why, just skip the question)?
    3. Was there "some community agreement" around C++/CX?
    4. Is C++/CX one of the things the community "has been clamoring for"?
    5. Is C++/CX something that is "not proprietary but rather the opposite: thing we already know is certain or likely to come" in the next version of the C++ standard and which you "hope all compiler vendors will provide too"?
    6. Are you encouraging other vendors to implement C++/CX "to the benefit of everybody no matter whose tools they're using"?

    Taking them one at a time:

    1. It's not a brand-new set of extensions, rather it's essentially the same as C++/CLI. This was deliberate; once we realized were were on a path of doing language extensions again for the reasons I tried again to clarify in my note a minute ago, I did not want to create yet another different set of extensions. (There were several attempts from other people and teams within Microsoft to propose other extensions including many variants of the @ character, and despite considerable pressure to do that we steered away from the shoals of inventing yet another thing where you'd see code like @IFoo everywhere. There were so many that by the end of last year "hey, why don't we just use @ here" had become a running joke within our design team, because it had been proposed by so many people using so many different potential syntaxes for such a long time.)

    2. We think so, given the constraints I tried again to describe in my last comment. I haven't given up trying to find and answer the question here. Smiley Referring to that comment, it comes down to whether design requirement R2 is important to you, and whether you prefer choice B1 vs. B2 which are different ways to advocate for ISO C++ purity and minimize impurity.

    3. Yes, because C++/CX is C++/CLI (modulo spelling gcnew as ref new, and very minor differences such as when WinRT doesn't support one or two things that .NET does, like generic classes). C++/CLI is the only set of non-ISO C++ language extensions in the world that was developed openly in an international standardization process with the participation of a who's-who of the participants and officers of ISO C++ (WG21), including Bjarne, IBM, Intel, EDG, Dinkumware, Plum Hall, and others including notably experts from UK and France, whose contributions were very helpful and changed C++/CLI to make it better than it would otherwise have been. This involved holding design and standardization meetings around the world, co-located with WG21, over the course of two years, plus telecons, sharing all documents openly (a first for Ecma), and other open engagement. C++/CLI is now an international standard (Ecma-372) that anyone can freely implement; that's a good thing now, because I've already heard about other compiler vendors investigating implementing C++/CX, which to my knowledge nobody ever did for C++/CLI.

    4. Partly.

    • From a feature point of view, it does include things like properties, delegates, events, and other things on Bjarne's 2004 wishlist, including extensions that originated in C++/CLI and are now in ISO C++11, such as nullptr, enum class, override, and sealed/final all with exactly or very nearly C++/CLI syntax and semantics.
    • From a platform point of view, some developers were clamoring for doing better COM integration (e.g., to be able to do everything in one source file without extra files/tools), and despite that there will always be some who dislike any given design choice, we've had a lot of positive feedback from people who are glad that we finally let them do COM without MIDL.

    5. Yes, see above; parts of it have already been adopted in ISO C++11, and if the door opens for another round of language extensions then among the first to be submitted are likely to be things like properties/delegates/events which didn't make C++0x's priority list last time partly for lack of time and desire for more field experience with library vs. language approaches (which C++/CLI / C++/CX is helping to generate), but have always been of interest (see again Bjarne's 2004 wishlist).

    6. Yes. Just like with C++ AMP, which we also announced earlier this year as a VC11 feature; I know of multiple investigations/implementations in progress for non-Windows platforms, and we are actively helping those implementers with their implementations. This is a definite change from the past; our viewpoint is that anything we ship, including library interfaces (not necessarily the Windows-specific implementations), should be something that we'd be willing to encourage other implementations and to submit to standardization if there's interest. That's one reason many of our new libraries in VC++2010 and VC++11, like PPL and AMP, are using c_style_naming (the naming convention preferred by ISO C++ and Boost) except where we were specifically binding to something that already had a different strong naming convention (e.g., the Platform:: namespace VC++-specific WinRT wrappers we provide we chose to PascalCase for consistency since they were specific to WinRT).

  • GlenGlen

    @Herb

    Minor points:

    I believe the extensions you attribute to being "thanks to C++/CLI" are really more "thanks to Java" or someone prior to C++/CLI. I am surprised you keep stating this claim, I know you helped push them through to C++ but that's different from originating the basic concepts.

    I can't recall any significant language invention being particuarly attributable to Microsoft that ever became a remaining part of the core language, as bad as that sounds to say it. Maybe I am mistaken on that last part, sorry if I am. Bjarne doesn't even appear to be a strong supporter of sealed.

    Regarding properties, events and delegates, if they were of value to ISO, it's stunning that they aren't already in the language or weren't more widely debated this time around and more stunning why MS didn't at least propose them so either could happen or advance their definitions further - you already had all the experience you needed with them in C++/CLI and they feature again in C++/CX unchanged.

    I hear your reasoning on that, but my observations don't leave me too disposed to the idea they will come in the next round and if they don't arrive in a compatible way with the C++/CLI/CX version of them, you can be sure MS wont support them? It would appear to mess the design up of everything if they did; arguably like how the basic .NET container classes and the interfaces that used them became a blot on the landscape once the typed version ones became available.

    Major points:

    Regarding goals B1, and B2.

    My opinion is that a Component technology is not like the technology of, say a GUI library; because a component technology is not "like a library" at all - it is the "essence of library" i.e. any library, especially *my* library.

    C++/CX as it stands requires me to wrap all of my libraries - my classes, i.e. the ones that *I* produce; at the class level. Which is why it introduces it's own class to do this. That one statement alone is huge. If Bjarne really thinks this is a good idea (and I know you two are friends so I'm open to what this statement will yield), but I want to see him say it because its too big of an idea/language extension to trust to MS alone. It's virtually unheard to give a dog two heads and find anything less that one or both of them dies, or it becomes a heck of a lot more expensive too feed!! That's C++/CX!!

    Unlike, say, a Win32 GUI API, that you wrap, C++/CX wraps you, at the class level, so the borders are everywhere you are yourself, and you do the wrapping yourself. I don't believe in that. I certainly don't believe in that where the method is much less than transparent.

    When you think it should be as transparent as possible, talk of language extensions become really about saying you think none are needed (the goal is for the wrappers to be transparent wrapper after all) or you can have as many as you like but they wont be needed often and likely [[attributes]] might be sufficient in most cases. Who knows exactly, that's what I'm here to work out.

    Whatever the means, wrapping is what makes C++/CX not viable in of itself IMO. Anything that doesn't virtually completely remove the burden of wrapping your own classes (even if you could justify the need to do it to start with, which I am not yet sold on either), is wrong; because it harms C++ productivity no matter how you do it - unless you don't do it. That's my stance, don't do it.

    If the problem can't be solved in a transparent way, either the platform model is too complicated or it will harm C++.

    If you rush out now and C++/CX'ify your code now, two years from now the problem space will be made transparent by someone (MS or a competitor) or the platform will die, and you'll have a load of rubbish code, if you haven't coded very carefully - a skill most people will lack or have time for. Anyone with a big C++/CLI code base probably already feels like that today, I bet.

    So that's my opinion, don't do it. Until the problem I have stated is fixed (i.e. the problem becomes transparent), C++/CX is half baked like COM was before it.

    C++ cannot afford to be the battle ground between component technologies, it needs to be a case of IJW or the platform is wrong or the language is being harmed. How many other languages are you going to extend or recommend get two notions of class?

    Please Herb, or anyone, tell me your thoughts on that lot.

    I will post again to elaborate but thats the basic issue for me: C++/CX doesn't make "C++ good for writing libraries" it makes "borders everywhere" and makes it "expensive for writing libraries".

  • @Glen:

    Re: "I believe the extensions you attribute to being "thanks to C++/CLI" are really more "thanks to Java" or someone prior to C++/CLI. I am surprised you keep stating this claim, I know you helped push them through to C++ but that's different from originating the basic concepts."

    Of course many languages, including before Java, had some of these concepts (spelled in C++/CLI and C++11 as nullptr, enum class, override and sealed/final). But ISO C++11 had many alternatives for each one (choice of keyword, grammar position, attribute or not, etc.), and standardized exactly C++/CLI's syntax and semantics with few or no tweaks. The C++11 keyword "nullptr" and the "enum class" syntax and semantics are C++/CLI. For the other two it's even clearer: "override" et al. are ISO C++'s very first ever contextual keywords; there were many other options, from attributes to fully reserved words, and C++11 followed directly the trail blazed by C++/CLI to make them contextual even though that was a major novelty for C++11, but because it had been shown to be a great option that works seamlessly in practice based on the field experience with C++/CLI it was considered safe for standardization. I consider that a big win for the whole C++ community, because it would have been beyond awful to have override and final be [[override]] and [[final]] attribute, or based_check_override and base_check_final deliberately-uglified-to-not-break-existing-code keywords, which were the other major options n the table.

    You really don't get field experience with future-standard language features unless someone implements them as an extension, and so C++/CLI / C++/CX has turned out to be a sort of "Boost for language features" and I expect more features to be proposed for ISO C++.

     

    Re: "Regarding properties, events and delegates, if they were of value to ISO, it's stunning that they aren't already in the language or weren't more widely debated this time around and more stunning why MS didn't at least propose them so either could happen or advance their definitions further - you already had all the experience you needed with them in C++/CLI and they feature again in C++/CX unchanged."

    Good question, two reasons (caveat: I'm going from memory here, which can be dangerous):

    1. They were cut from C++0x for scope/interest: As I recall, deferring properties/delegates/events was more of a C++0x scope issue and the availability of experts willing to contribute their time to develop the proposal. Only so much was going to fit into C++0x, and a lot of good ideas had to be cut early on because we couldn't afford the development time and/or didn't have the right people available. Even at that, we didn't cut enough -- x was hex.
    2. The timing was wrong: If I recall correctly, properties/delegates/events were cut/deferred from C++0x before C++/CLI existed. Remember, C++0x work began in 2002, Bjarne's wishlist that I linked to was as of 2004, and the C++/CLI standard was not finished until December 2005.

     

    Re: "Regarding goals B1, and B2."

    I'm not clear from your answer which you prefer, B1 or B2?

     

    Re: "C++/CX as it stands requires me to wrap all of my libraries - my classes, i.e. the ones that *I* produce; at the class level"

    C++/CX doesn't do that, WinRT does. How is this different from COM or CORBA?

    ISO C++11 doesn't have ABI-safe components or modules; it can't express those. That's not surprising, because the design requirements for C++ classes and ABI-safe classes are inherently different and incompatible:

    • C++ is all about efficiency and direct access, and so C++ classes and the C++ object model guarantee that the compiler has direct access to the bits of an object to enable full optimization and "you don't pay for what you don't use" etc.
    • A component object model is all about decoupling and truly encapsulating, and so ABI-safe classes and the ABI-safe object model are all about hiding the bits of an object to decouple caller and callee.

    So to have ABI-safe component types inherently requires non-ISO C++ code somewhere.[*] The only question I can see on this thread is where to put that non-ISO C++ -- and putting it in a separate MIDL file with its own language extensions and compiler is no less of an extension and no more portable than putting the extensions in the same source file.

    • [*] Yes, there are styles where by sheer dint of conventions and discipline you can try to stay in an ABI-safe subset of C++ by Pimpl'ing everything, using interfaces only, following refcounting conventions by hand, etc., but: Angel discipline + convention alone is insufficient because even those Pimpl-everything types aren't portable across even two C++ compilers unless the compilers have compatibility settings that guarantee at least identical calling conventions, vtbl layouts, and exception handling mechanics; (b) even if it were possible to do by sheer effort I find the argument unconvincing because you can extend the same reasoning to say that you can do it in plain C and don't need C++ either; and (c) this set of conventions is exactly where COM and CORBA started so we know where the path leads.)

     

    Re: "Unlike, say, a Win32 GUI API, that you wrap, C++/CX wraps you, at the class level"

    (Again, this should say WinRT.)

    Right, like COM and CORBA and the .NET CLR, WinRT is a runtime environment with its own object model, not just a library. The task my team was given was how to enable C++ programmers to consume and author types in that universe with as minimal impact to C++ code as possible by minimizing the amount of code/tools that programmers would have to write/use to work with the extensions.

     

    Re: "If Bjarne really thinks this is a good idea"

    Just to be clear, I was not claiming any of those participants endorse C++/CLI, I was saying that they actively invested effort to contribute to the design of C++/CLI to make it the best quality it could be and as compatible and conflict-free with ISO C++ as possible. Bjarne prefers no extensions at all whenever possible, and wishes we needed to do fewer, while recognizing that extensions are necessary to deal with different operating environments (such as in this case).

     

    Re: "Whatever the means, wrapping is what makes C++/CX not viable in of itself IMO. Anything that doesn't virtually completely remove the burden of wrapping your own classes (even if you could justify the need to do it to start with, which I am not yet sold on either), is wrong; because it harms C++ productivity no matter how you do it - unless you don't do it. That's my stance, don't do it. If the problem can't be solved in a transparent way, either the platform model is too complicated or it will harm C++."

    See above, the fundamental difference, starting from basic requirements, between C++ types and ABI-safe component types.

    How can you expose an API surface to any of WinRT, COM, CORBA, or .NET CLR without using their types? The question isn't whether wrapping is necessary; it is. (If it weren't, then generations of COM and CORBA vendors have been somehow naive.) The question is only how to spell the extensions and where to put them.

    Herb

  • ISO 14882ISO 14882

    @JimSpringfield

    "Regarding partial classes, I explained that there is often more than just putting additional methods and data into a class."

    Thank you for your explanation. However, I must admit I'm still not convinced at all, because:

    "Often, you need to modify the set of bases for the class."

    C# has partial classes, yet the designer puts the base class in the user-editable file. So this doesn't seem important at all.

    "Sometimes, you also need to inject code into constructors/destructors or other functions, although usually that can be worked around."

    Again, C# has partial classes, yet the designer generates InitializeComponents() method that you call in the constructor inside the user-editable file. So this seems unimportant too since the C# guys have done it this way anyway.

    "Also, doing a #include inside of a class would make it really hard on the browsing tools within the IDE."

    Even if so, this is a really weak reason to provide a new core language feature. It's rather a strong reason to improve the browsing tools – after all, this is a perfectly valid C++ code so the tools should be able to deal with it anyway. The only difficulty I see is providing Intellisense etc. in the generated file, but since it's assumed not to be edited by the user then that's not a problem at all.

    "You can take a look at some of my posts on Intellisense/browsing for more background."

    I will look for them, thanks for the info.

    "Regarding CreateInstance and WRL. WRL doesn't use ^ and creates objects similarly to how ATL did it. "Ref new" returns a ^, not a *. If you get rid of hats (or similarly marked up pointers), then you don't need it."

    Exactly – if you get rid of hats. C++ already has a very good means of doing exactly such things without inventing new syntax like ref new and hats. No need to look far – Standard Library has shared_ptr<T> and make_shared<T>(args...). Then why ^ and ref new instead of just winrt_ptr<T> and make_winrt<T>(args...)?

    If those two extensions are basically all that is needed for C++ code consuming WinRT components then it is even more appealing reason to not implement them as extensions. Imagine all those external tools, I'm not even talking about other compilers, but lint-like analysers, documentation generators, code editors or reformatters, which would be able to digest a lot of C++/CX code without problems should it only use winrt_ptr/make_winrt, but instead they will choke on ^ and ref new. It's so low-hanging fruit to make C++/CX just a bit more portable, so why you're ruining it all with the hats?

    Offtopic: could someone please tell me how one gets text formatting in the comments? HTML tags? BBCode? I couldn't find anything about this on channel9 pages...

  • ISO 14882ISO 14882

    @Glen

    "Regarding properties, events and delegates, if they were of value to ISO, it's stunning that they aren't already in the language or weren't more widely debated this time around"

    As to events and delegates – I believe that this is not because they are of no value to ISO, but because a) there was already too much important stuff put into C++11 for them to also make it and b) they don't need any core language support. A good example is Boost.Signals library which is a pure library solution yet it provides way more functionality than .NET/WinRT delegates and events (automatic disconnection and combining return values to name a few). If/when C++ adopts events and delegates, it's more probable they will be library-based (and quite likely based od Boost.Signals). And when that happens, we'll have yet another source of incompatibility since there will be yet another thing in C++/CX done differently than in C++.

  • CharlesCharles Welcome Change

    @ISO 14882: Re formatting... For a variety of reasons, we do not enable text formatting (HTML) beyond newlines for anonymous posts. It's a policy, not a bug.

    By design.

    C

  • GlenGlen

    @Herb

    Hurrahh that some smart people went to lengths to avoid using simple keywords; but it "befounds" the rest of us average joes that anyone would have ever have wasted time proposing or considering attributes for those roles in the first place, even given the sheer fugly factor alone!!

    If some of the people didn't get so tied up in knots about such non starters, maybe they'd have had time to properly consider properties, delegates and events!!

    Yes I appreciate that you were on the right side of this particular case. :)

    Not to sound ungrateful though, the reality of the man on the street is this: as long as the WG21 team can agree, that the concepts keywords are serving are useful - which should have been relatively easy since Java et al had already proved the ones we were talking about (i.e. nullptr, override, etc., which was my point) - the rest of us mere mortals would have accepted even full keywords in this context and dealt with the consequences!

    I don't mean to downplay your invention of a super keyword but to say anything other elides these facts.

    That microsoft firmed up an implementation of some of those ideas, I am willing to accept, but your comments tend to suggest that the majority of invention came from C++/CLI and now that C++/CLI was required to proove them for the cases we were talking about.

    I think you will find the mainstream view is that the core ideas were not new (as you agree) but also that Java piloted those features sufficiently to see the value of them and that it elides a lot of reality to credit C++/CLI with the origin of those features, so you shouldn't do it. Still, like I said it's a minor point, we can agree to disagree. I still appreciate the work done on it.

    For its size though, Microsoft has arguably never contributed substantially to C++ yet, but it has benefited greatly from it. It just doesn't have a good history of invention there.

    Which leads me on to Properties, Events and Delegates, your comments suggest that ISO might pick it up, but what I was getting at was what @ISO believes: that if they come at all, they are likely to be library based. So the question remains the same: where will be then? Its a worry. Your cart is before the horse.

    I take your point about fusing C++/CX and WinRT. But never the less, their existance is fused. I don't see that one exists without the other? ref class has no future without WinRT?

    As far as B1 or B2 goes, I can't answer that right now, but I'll post separately my view of the whole MS deal and you can tell me where I'm missing the tricks there or where the deal can get better.

  • @Glen wrote: "If the problem can't be solved in a transparent way, either the platform model is too complicated or it will harm C++."

    I get it -- you want it to be true that ISO C++'s great flexibility is so powerful that it's sufficient to directly express all object models. It's frustrating to be told by people who it seems ought to know better that it isn't that way. I understand; I wish it were true, too.

    You may not realize how much I understand your frustration.

    Let me tell you story.

     

    In the Way-Back Machine

    In December 2003, an effort to revise the Managed Extensions to C++ was already underway (an effort that would later be called C++/CLI), but I was not participating in it at the time and in fact had heard little about it. I had joined Microsoft just the year before and was still figuring out the huge company and its platforms. I already had a lot of C++ experience and love, as did the other people on the team, but was still drinking from the fire hose of information and trying to absorb as fast as I could all the deep details of the platform and tools that people around me already knew.

    That December, the C++/CLI effort had hit a technical and organizational roadblock, and people started coming to me to look for help. In the end I asked for, and was given, the job of leading the design team. As you can imagine, this always presents tensions and challenges for a project team already in midstream, and especially when the newcomer has some pretty hard-nosed design sensibilities about doing things the ISO C++ way.

    For the first several months I made a real pain of myself, insisting on understanding the deep rationale for every single feature because I just couldn't believe such a set of language extensions was needed. For example, I asked "why do we need a new class category, why doesn't it just work to have 'class X : System::Object' be an inheritance tag from a magic type that the compiler can treat specially?" and spent several weeks trying to make it work, and several dozen similar questions -- many similar to questions in this thread. And my probing was most of the time not specifically whether a language extension was needed; the questions were deeper, to find the goals and constraints -- 'what semantics need to be achieved?', 'what does the code generation have to be?', 'what is the IL we have to map to and round-trip with?', 'how does the compacting garbage collector work?', 'why can't regular pointers point into the GC heap?', 'what are the exact semantics of pinning an object's memory?', and so forth.

    In the end, once I grokked the main design constraints, I like to think that I did make a number of contributions that improved and simplified the design quite a lot. But at first I was really wishing it could be 'just ISO C++,' and it was painful when I really began to understand the deep reasons why wishing wouldn't make it so.

    Over the course of those first several months, I gradually realized that a few patterns were emerging in my thinking, notably (but not only): 1. I kept trying to make a language feature look like a library, but it still required compiler knowledge and so it was still a language feature in library-syntax clothing and I was only fooling myself that that somehow made it more like a library. 2. I kept discovering differences where this really was a foreign object model that couldn't be expressed directly in ISO C++ any more than full ISO C++ classes with virtual functions could be expressed directly in ISO C.

    I see the same patterns here in this thread, and I understand completely because I said the same kinds of things for months in early 2004 during the C++/CLI design effort when I didn't understand the full problem. I appreciate the patience the team had with me as I absorbed it, but even then it took months in daily meetings in rooms with whiteboards and high-bandwidth interaction.

    In this comment format, I can't possibly convey all that learning derived from months of face-to-face interaction with the best experts on the technologies, but maybe I can distill some key learnings and why I felt they were so important in changing my understanding of the nature of the problem.

     

    Pursuing an Analogy: A General Answer to "Why Language Extensions"

    Let me pursue the analogy with expressing virtual functions in ISO C, because it's a very good one that directly applies to expressing foreign object models in ISO C++.

    In the past, people could have (and sometimes did) argue at great length that C is enough (heck, it's Turing-complete and you can write OSes in it) so "you don't need C++ classes and 'virtual' etc. added to the C language, you can write your own vtables in C" and look here are three projects I can cite that did that...

    ... Yes, clearly, you can. But that "you can" completely glosses over the costs, including the usability and other drawbacks of doing it by hand, including the quantity of code you write, the quality of the code you write, the quality of error messages, the run-time performance, and the tooling difficulty and quality. If that list sounds familiar because I've mentioned those same things already earlier in the thread, it's because it's what always happens when you fail to expose high-level abstractions and instead use low-level abstractions plus coding conventions.

    So how would you answer someone who presses you with the question, "well, can you tell us why it isn't possible to just write our own vtables in C"? Of course it's possible -- and at this point, before you can say more, they may tend to interrupt with 'ha! it's possible, you admit it! so you can have no valid reason not to have done it in just ISO C' -- ; but that doesn't change the fact that it's not a good solution because you're missing abstractions that belong in the language because they require compiler knowledge.

    Key point: As soon as something requires compiler knowledge, it's a language feature. Pushing the language extensions somewhere else, like to a MIDL language+tool, is just squeezing the toothpaste tube and moving the extension to somewhere else in the design space; it's not removing the need for language extensions.

    Corollary: Magic libraries and compiler code generation tools are language extensions. As soon as something requires compiler knowledge, it's not a normal library type, and wishing won't make it so. Neither will giving it a library-like syntax.

    Note that the answer to nearly all questions of the form "why did you need a language extension for X" is "because X required compiler knowledge." The reason I say "nearly all" is:

    • In a few cases the answer is "for usability." For example, usability is the reason C++11 added "auto" and "range-for" and C++/CLI and C++/CX added ^. They're only conveniences, but deemed important enough to bake into the language because their convenience is so useful and frequent that the sugar they provide yields a high benefit even though they're just sugar over other existing language features.
    • But nearly always it's "because X required compiler knowledge." For example, that's the reason C++11 added decltype (the twin of auto), override, final, lambdas, nullptr, enum class, move semantics and rvalue references, uniform initialization, initializer lists, constexpr, variadic templates, and nearly everything else. Libraries simply would not do. (Before you say "but initializer_list is a library feature," I slyly and deliberately included that in the list to underscore the point -- initializer_list is not fully a library feature, because the language is aware of the type and gives it special semantics and code generation; you cannot write initializer_list as a library in a C++98 compiler and get its full semantics).

     

    Limitations of the World's Most Flexible Object Model

    Finally, the thing that was perhaps hardest to accept was that this beautifully flexible ISO C++ object model that seemed like it could express anything, this so wonderfully controllable and flexible and efficient object model, could not after all directly express all interesting object models. Some object models would stay foreign (at least until added to some future ISO C++) -- not just dynamically typed object models, but even statically typed object models that have different rules and constraints. So the realization was the following:

    Key point: There are interesting object models that are not directly expressible in C++. "Directly" means in the language without relying deeply on convention and discipline; you can express anything in assembler via convention and discipline, but that observation is neither helpful nor interesting. "Other object models" mean ones that reflect different object layout assumptions (e.g., hiding data rather than exposing it the way the C++ object model assumes and requires), different static and dynamic restrictions, and even different language rules (e.g., deep virtual dispatch in constructors). When you need to bind to them, and you want to do it well with best quality and performance and toolability, you need language extensions.

    Corollary: Using those object models well from C++ requires a language-level binding. It can be done without a language binding to the same degree as virtual calls can be done using hand-coded vtables in C.

    Let's return one more time to virtual functions expressed in ISO C.

    Consider what would happen if you really tried hard to do virtual functions in C without language extensions. You could imagine creating a wonderful set of C macros (just like #import-enhancing macros) that automates a lot of the repetitive coding for you, and the resulting code may even look reasonably nice. (After all, when we're in this "imagine if" mode before doing real detailed systems prototyping things always look rosier and feasible because you haven't found the problems and limits yet; but let's assume what I just described was actually possible in this case for C macros simulating virtual functions.) (And I said "you could imagine creating" on purpose -- that's what this thread is often doing.)

    Here's what we know you will never get without a language feature:

    • You will never get the code elegance and readability. People using those macros will always write more verbose code than just adding the one word "virtual" to a function signature. (The same is true in C++/CX of, say, "ref".)
    • You will never get as robust code. The code that people write will definitely be more brittle -- if nothing else, there will be many more places to spell it wrong because it relies on more-complex conventions and so there are more points of typing/thinking failure. Further, when you say "virtual" you declare your intent and language rules kick in to do two things on your behalf: 1. The language rules do a lot of work and code generation automatically, and they'll get those detailed vtable mechanics right every time (modulo compiler bugs) because it's the compiler that's writing the code, not you. 2. The language rules can often make it impossible to write certain classes of errors even by mistake, because the language can often be designed to make it impossible to say some nonsensical things. When you roll your own vtables, you're not declaring any intent, all the code generation is by hand or at best semiautomated, and there are no language guard rails to help you do it right.
    • You will never get the same high quality of error messages. When "virtual" is a keyword you are clearly declaring your intent, the language has rules that enforce you did it right, and the compiler can tell you far more exactly when you got it wrong -- at compile time. When you roll your own vtables, most errors will be at link time or run time rather than compile time, and will be far more cryptic and less actionable.
    • You will never get the same run-time performance optimizability. It's important to think about why this is fundamentally true: It too derives from expressing intent. When you don't declare your intent in a language-understood way, you cripple your compiler's and optimizer's ability to help you. For example, in VC++11 we are doing aggressive devirtualization which can result in some major performance wins. Good luck getting that optimization without the "virtual" keyword and instead using hand-coded vtables in C, because the compiler and optimizer will have no idea what you're trying to do. (Note that this is the same reason why C++ templated algorithms taking iterators and lambda functions are routinely faster than hand-coded C loops with direct pointer increment and dereference instructions! That higher-level abstractions just naturally enable performance optimization is just a fact of life, an inherent benefit that results from the fact that letting your tools know more about what you're doing directly increases their ability to help you.)
    • You will never get the ease of producing high-quality tooling. Yes, you can code your vtables in C by convention -- but don't expect to get as nice a debugger or object browser, and possibly no class wizard or class inspector at all.

    That's what (well-designed) language abstractions always give you over coding convention + discipline: More concise, more elegant code. More robust code. Higher quality error messages. More performance optimization opportunities. Better toolability. This is not wishful idealism; it's inherently true, every time.

    All of these things -- said above about language extensions to C for dealing with virtual functions -- apply to language extensions for binding C++ to foreign object models, for they are simply always true for all language extensions that eliminate conventions + discipline.

    ISO C just isn't suited to natively doing OO programming with virtual functions, any more than ISO C++ is suited to doing a component object model with true encapsulation and ABI safety. ISO C and C++ are both incredibly useful, powerful, and flexible languages; but an important part of using a power tool is to understand its limits. Sometimes that takes time and deep experience at the boundaries.

     

    @Glen wrote: "How many other languages are you going to extend or recommend get two notions of class?"

    Let me ask you a counter-question, please.

    What would you say if you were proposing virtual functions for C, and someone asked, "Why do you recommend getting two notions of functions? Functions are functions, darn it, everyone knows that, virtual functions are just functions and I'm sure you can express them in ISO C without extensions, we have function pointers and everything you need."

    Two questions:

    1. How would you answer that?
    2. When your answer begins with, "Well yes, you can, but..." -- now how do you keep the person listening after that first four-word sound bite that may tell him what he wants to hear, but isn't anywhere close to being the complete truth?

     

    It took me a while to get all this through my head, so I know it takes time.

    I don't know if this will help, but maybe it will.

  • @Glen: "Hurrahh that some smart people went to lengths to avoid using simple keywords; but it "befounds" the rest of us average joes that anyone would have ever have wasted time proposing or considering attributes for those roles in the first place, even given the sheer fugly factor alone!!"

    Forgive me, but this is a perfect example: "I can't imagine why it was so hard to get ISO C++ to not use simple keywords virtual override/final" is a perfect parallel to the questions about "I can't imagine why it should be so hard to surface WinRT in ISO C++" -- you have to know the many social and technical constraints on the problem to see why things that everyone initially believes ought to be easy (or easier) really aren't.

    The short answer in this case is that:

    • WG21 places a very high priority on minimizing potential breakage of existing code, which really is important because a lot of people depend on third-party headers they can't edit and so forth. So WG21 wouldn't take "nice" common words as new reserved words, because that would break any code that used those words as identifiers.
    • WG21 had never done contextual keywords before and is allergic to novelties like that. I'm still happy-but-amazed that they accepted contextual keywords into the standard.
    • The only remaining major alternatives were to use uglified_keywords that would be very unlikely to break existing code, or to use the new [[attribute]] syntax (but it is entirely nonobvious to many people at first why disguising language extensions using attributes is a horrible idea that leads to an awful place).

    I personally led the charge on this one, at multiple meetings. If I hadn't done that, today we would have a C++11 with [[override]] and [[virtual]] -- not only in that hideous style, but in weird grammar positions. That's what was the default solution already voted into the draft standard, and what we would ship with unless there was consensus to switch to some other specific alternative (which is a very high bar).

     

    @Glen: "Not to sound ungrateful though, the reality of the man on the street is this: as long as the WG21 team can agree, that the concepts keywords are serving are useful - which should have been relatively easy since Java et al had already proved the ones we were talking about (i.e. nullptr, override, etc., which was my point) - the rest of us mere mortals would have accepted even full keywords in this context and dealt with the consequences! I don't mean to downplay your invention of a super keyword but to say anything other elides these facts."

    That's simply not true or realistic. There are billions and billions of lines of working C++ code in the world. Breaking even 0.1% of the code in the world is a major breaking change that would directly hurt adoption of the new standard. Compatibility is king for C++ -- it always has been, because if C++ had not been essentially 100% C-compatible, essentially a strict superset of C, it would never have been widely used outside of AT&T. Even now C++ faces great pressure to remain a nearly perfectly compatible superset of C, to the point where WG21 felt obliged to formally add C99's preprocessor extensions and the entire C99 standard library to C++11.

     

    @Glen: "That microsoft firmed up an implementation of some of those ideas, I am willing to accept, but your comments tend to suggest that the majority of invention came from C++/CLI and now that C++/CLI was required to proove them for the cases we were talking about. I think you will find the mainstream view is that the core ideas were not new (as you agree) but also that Java piloted those features sufficiently to see the value of them and that it elides a lot of reality to credit C++/CLI with the origin of those features, so you shouldn't do it. Still, like I said it's a minor point, we can agree to disagree. I still appreciate the work done on it."

    The point wasn't the feature, it was the difficult legwork of how to expose the feature specifically in C++, and specifically with perfect backward compatibility with existing C++ code. The answers were not obvious.

     

    @Glen: "I take your point about fusing C++/CX and WinRT. But never the less, their existance is fused. I don't see that one exists without the other? ref class has no future without WinRT?"

    Not only does it have a future, but "ref class" already had a past even before C++/CX and WinRT in C++/CLI and .NET -- it has now successfully bound to two very different (if related) object models, namely .NET and WinRT. And we have enough experience now to be pretty sure if we need to ever bind to a new static OO object model, we can reuse the same language extensions with a new switch to signify the new target (just as today with /clr they target .NET, and with /ZW they target WinRT), not invent something new. (However, I don't know yet if they would be sufficient to bind to a dynamic type system's object model, which is both similar and different.)

  • Thanks to both Jim and Herb for the replies. This is a reply to Herb, with another short reply and a short reply to Jim following.

    @hsutter

    Before I go further, let me sanity-check something: Do we agree that the route of "extending TLB #import" leads to a full ATL + MIDL like approach?

    No. ATL + MIDL is a reasonable way to write code, but we are talking about something else. We are talking about not only "extending TLB #import" to cover WinRT modules, but also about doing the reverse of #import, that is, parsing regular C++ code and generating wrapper C++ code in order to expose regular code to WinRT.

    Here is an example:

    // ISO C++
    struct I1 : public IInspectable {
    virtual void F() = 0;
    virtual std::wstring G(int) = 0;
    };
    struct I2 : public I1 {
    virtual winrt_ptr<I1> H() = 0;
    };
    class C : public I2 {
    public:
    C();
    ...
    };

    The developer would write the above code, use class C in a regular way in the module, and direct the compiler to expose C for consumption by WinRT. There are many different ways to direct the compiler to do this (pragmas, __declspec, predefined bases, separate command line switches, etc), we can talk about pros and cons of each. The compiler would take the above code and generate wrapper C++ code representing C, I2 and I1 for WinRT. I1 would translate into __internal_I1 and would derive from IInspectable. I2 would translate to __internal_I2 and would derive fro IInspectable as well. __internal_I1::G would return a WinRT string. __internal_I2::H would return a refcounted pointer to __internal_I1. There would be a factory for creating a wrapper for C, which would return a refcounted pointer to it. And so on.

    We can discuss how to do the translation for delegates, events and everything else. This is a lot to talk about, but from what we see, for every feature a regular C++ mapping of concepts can be done.

    Example syntax for events:

    // ISO C++
    class C ...
    {
    ...
    virtual winrt_event<int()>& E() { return _e; }
    ...
    };
    ...
    c.E() += []{ return 2; }; // or 'c->' if c is winrt_ptr<C>

    To create an event, you create a member of the type winrt_event<>, then return a reference to that member via an interface function. When you direct the compiler to expose your class for consumption by WinRT, it generates C++ wrapper code that maps winrt_event<> to equivalent constructs in WinRT. If you later import the same component in a different C++ project via #import, the compiler generates C++ wrapper code that maps WinRT constructs back to winrt_event<>. You subscribe to an event using the plus operator or the Subscribe function on winrt_event<>. The latter lets you save a cookie you can use pass to the Unsubscribe function on winrt_event<>.

    If you subscribe to an event you expose in the same project, the call goes directly through C++, without passing through WinRT. This is a huge plus for many reasons (eg, optimization), but in case this ever becomes a minus, you can make the call go through WinRT by directing the compiler to export the class that exposes the event and then reimporting the result via #import.

    I hope the above is sufficiently clear.

    On to the post:

    So I'll assume (please correct me if I'm wrong) that we agree that extending the #import model for the consumption side means that the authoring side would employ something like a MIDL language and compiler/toolchain -- so that programmers could specify the additional information that is needed for metadata -- plus a supporting structure of macros, base classes, and/or ATL-like smart pointers. Correct?

    No. Smart pointers, base classes and possibly macros - yes. MIDL - no. I am not convinced that MIDL is worse than C++/CX either, but right now let's concentrate on using straight C++ without MIDL.

    At the outset of the project, my team was asked by our management to take as primary design requirements that we find a programming model that should: R1. Enable full power and control, including both consumption and authoring. ... R2. Be as simple and elegant as possible for the developer.

    Good goals. The approach proposed above achieves both - the wrapper classes allow R2 while being thin enough not to harm R1. It is possible to capture the code generated for wrapper classes and partially rewrite / reuse it to get more R1 if one needs this.

    A. What is the minimal code syntax and build steps it would it take to express this in a MIDL-style approach, and across how many source/intermediate files? What's the best we could do in that kind of alternative approach?

    For the sake of completeness:

    // ISO C++
    class Screen {
    public:
    int DrawLine( Point x, Point y );
    };
    Screen s;
    s.DrawLine( Point(10,40), Point(20,50) );

    B. How do you feel about these two goals? 1. Minimize the actual amount of non-portable non-ISO C++ code/tools developers have to write/use to use WinRT. 2. Make the code in the .cpp file itself appear to be using a C++ library, even though it actually is not (it is generated from Windows-specific language/extensions that are just located in a different non-.cpp file).

    Ideally, the only non-portable non-ISO C++ code is #import and #pragmas. There is nothing wrong with having generated code. The requirements on the original code from which the code is generated do not have to be artificial. We are trying to add the ABI so that we can cross over to other languages and technologies, fine, let's do this by generating additional code and using that when we are crossing over. When we don't have to cross over, let's just use (instantiate, call, etc) the original code as is, to the maximum extent possible. Should I elaborate or is what I am saying here clear?

    I strongly disagree that C++/CX minimizes the actual amount of non-portable non-ISO C++ code developers have to write to use WinRT. Yes, the above example is 6 lines of code in total and you turn it into C++/CX by adding a single 'ref' keyword, but this single 'ref' keyword makes all of the 6 lines non-ISO. 'Screen s;' looks deceptively like ISO, but if 'Screen' is a ref class, it is not ISO, because the ISO standard does not say what the compiler has to do to create an instance of a ref class. Same for the call to 's.DrawLine', the ISO standard does not say what the compiler has to do to call an instance of a ref class.

    If we try and evolve your example just a tiny bit, the non-ISO nature of it will become much more apparent. Say, Screen has to be allocated dynamically, then 'Screen s' becomes 'Screen^ s = ref new Screen()'. Whoa, we added a hat and a second ref. That's 3 keywords for 6 lines now. If arguments to DrawLine have to be WinRT objects as well, there are more hats and refs. If we proceed in that direction we will very soon flood a good deal of our code with hats and refs. And we aren't even talking about non-C++ things like events yet, we are just talking about the trivial example you have chosen to start from.

    Compare this mess with wrapper classes.

    One can view C++ as a framework for using different technologies. We can use very different technologies like, say, ODBC and OLEDB, simultaneously, there are a lot of very diverse technologies like that which we can use, and we can do it all with next to no changes to the language (#import or an analog is all that is required, if that). What C++/CX does is take one such technology (WinRT) and shove it down into the language, breaking internal logic in many places along the way. What the proposed wrapper classes do is keep WinRT outside the language, making it cooperate via a layer of adapter code. It is clear to me that the approach with wrapper classes is a vastly better one.

  • @hsutter:

    On the interview (let's get fluff out of the way):

    I still agree with pretty much everything I said, including the need for further conformance to the new C++ standard now that it has stabilized and was published last month.

    Sorry, no.

    You equate C++/CX with C++/CLI point blank ignoring that while they look similarly, they wrap different underlying technologies, and what exactly they wrap matters. Suppose someone comes up with an idea of using hat pointers and ref new as an alternative way to work with regular C++ classes. Would you support the idea of such a language extension? Of course, not. You see, what exact implementation details hide behind the proposed syntax and rules matters. If the standards committee or the larger C++ community agrees on some aspect of C++/CLI, it does not at all follow that they would agree on the same aspect of C++/CX. Saying that you did it all right with C++/CLI and so it is all automatically right with C++/CX as well because it uses the same syntax and certain concepts are similar, too, is wrong. You simply can't say this, this isn't true.

    Then again, did you really do everything right with C++/CLI? Take point 5, where you say a language extension should be something "not proprietary but rather the opposite: thing we already know is certain or likely to come" in the next version of the C++ standard and which you "hope all compiler vendors will provide too"? Is C++/CLI part of C++11? Is it certain to come in the next version of the C++ standard? Is C++/CLI provided or going to be provided by any major compiler vendor? You had more than 5 years, how much longer do we have to wait to see what you are talking about as a requirement for a language extension happen for C++/CLI? Is it going to happen at all?

    As a side note, yes, C++/CLI is an ECMA standard, but that's not at all what we are after here and not what you have been talking about in the interview. The exact wording in the interview was: "things we already know are certain or likely to come in C++0x and which we hope all compiler vendors will provide too". We are talking about making extensions to C++, there is only one standard that really matters here - the ISO C++ standard for the language itself. It is nice if things outside of the standard are somewhat structured and standardized, but let's not be silly here, when we are talking about standard-compliant C++ code we mean only one standard - the ISO C++ one.

    Same with points other than 5.

    Since someone mentioned Bjarne Stroustrup, let's hear what he thinks of C++/CLI, too:

    "I am happy that it makes every feature of the CLI easily accessible from C++ and happy that C++/CLI is a far better language than its predecessor "Managed C++". However, I am less happy that C++/CLI achieves its goals by essentially augmenting C++ with a separate language feature for each feature of CLI (interfaces, properties, generics, pointers, inheritance, enumerations, and much, much more). This will be a major source of confusion (whatever anyone does or says). The wealth of new language facilities in C++/CLI compared to ISO Standard C++ tempts programmers to write non-portable code that (often invisibly) become intimately tied to Microsoft Windows."

    Heh, maybe C++/CLI will not become part of ISO C++ after all. Maybe it is not such a good and clear way to extend the language as Herb Sutter from Microsoft suggests. Maybe we indeed won't have any compiler vendors other than Microsoft supporting it anytime soon.

    In sum, Herb, I am, frankly, amazed at your willingness to call black white, but... we aren't stupid. Black is black. White is white. What you did with C++/CX goes very much against the principles you outlined in the interview.

  • And a reply to Jim.

    @JimSpringfield:

    I think I have answered these. a) Yes b) n/a c) Because we didn't see this approach as the best solution for our users. We've tried to cover many of the issues that pushed us to C++/CX and I can understand if you disagree with some of them.

    Yes, this is settled. We are yet to determine what exact issues of wrapper classes pushed you to C++/CX, but we are talking about this right now so hopefully it will become clear soon.

    Regarding modules, we do NOT go through WinRT machinery when accessing a locally defined (within a binary) ref class. So, we can inline code and take advantage of other compiler optimizations.

    That's good. This suggests to me that when you see a 'ref class', you already split it into a regular C++ class (whose methods you can then inline) and a WinRT class (whose methods are stubs that call methods of the regular class). Thus, you are doing much of what we are arguing for already, you only have to go a couple more steps and (1) generate the wrapper WinRT class in the source form, and (2) get rid of 'ref', altering the code that parses code exported for WinRT to support regular C++ definitions for several things you now do through C++/CX-only features.

  • @Jim and PFYB:

     

     

     

  • I just want to add something which I think is vital, but was totally dis/missed from what Jim said (by the way Jim, thanks for honest answers). When Jim says:

    a) Yes b) n/a c) Because we didn't see this approach as the best solution for our users. We've tried to cover many of the issues that pushed us to C++/CX and I can understand if you disagree with some of them.

    I strongly believe that here is the crux - who are those users Jim mentions? Not C++ community surely? So who else is there? The answer is clear and obvious: The .NET crowd.

    MS as a very respectable company cannot just abandoned its current "users"  and tell them to feck off and that the technology they were lured to for over decade simply goes to butcher's house, and those folks need to learn new technology or learn a new phrase "DO YOU WANT FRIES WITH THAT?".

    No, MS knows that this wouldn't be the right strategic decision. In view of the fact that .NET will/is going to be slaughtered in the near future, MS had to come up with something better/clever in order to:

    a) keep a face

    b) confirms to its "users" that those who stick with it can depend on MS and will not be abandoned by this company

    c) keep an image of a respectable company

    c) holds to its "users"

    needed to ease the pain of switching between technologies.

    There were few options - better ones (Jim in his answer, admits that there is a way to do this with C++) and worse ones. Why MS picked worse one? Every one knows that people who works at MS are world class pros and experts, so how is it possible that MS made a mistake in judging what's good for it's customers. Exactly - just because it's worse for you it doesn't mean that is worse for MS customers, do you see it now? MS picked what's right for its customers, not what's right for you. Now when the cards are reveiled everything starts making perfect sense.

    Well, as they say in my old country if you don't know what it's all about it must be about money.  And if you think about this, MS knew who their customers/users are. There are .NET crowd. Not C++ folks.

    There are much more .NET devs in the world than C++. To MS was obvious that it has to try to keep those people by its side. In order to do that, familiar syntax and workings needed to be put in place. Just to make the switch from .NET to WinRT as easy and gentle as possible. That's why there also wasn't any pressure on adding C++11 features. What for? Their users don't need them so why would they bother?

    And what they (MS) could loose? Nothing really. .Net crowd will eventually switch to native WinRT - why wouldn't they? and those guys from C++ community who decide to use WinRT with the syntax from .NET world will be and extra addition to customers/users group of MS. Perfect plan. No chance for a loss.

     

     

  • MattMatt

    @PFYB

    Assuming an almost 100% ISO C++ simple and elegant solution for creation and consumption of WinRT objects can be designed (will definitely love that), could it be implemented by a third-party entity (e.g. not Microsoft) or are there some technical limitations?

  • WarrenWarren

    Thanks a bunch for wonderful posts, everyone.

    Jim Springfield, thanks for partly answering my question. It is good to know that large applications will be converted to WinRT, this wasn't the case with .NET and C++/CLI. Just to be sure, those applications are currently written in C++ and are going to use C++/CX and only on the border, right? Because I was asking about that. Thanks in advance.

    PFYB, your proposed code is exactly what I would like to write. I am very eager to hear what Microsoft people will say about that way to talk to WinRT.

    Herb Sutter, regarding your answer to Glen:

    Glen: "C++/CX as it stands requires me to wrap all of my libraries - my classes, i.e. the ones that *I* produce; at the class level"

    hsutter: "C++/CX doesn't do that, WinRT does."

    I believe we all understand that the requirement to wrap code to enforce a specific ABI comes from WinRT. But please note that .NET languages do all the required wrapping automatically, while with C++/CX a developer has to do the wrapping manually, all the while polluting the code with non-standard constructs. This is what I believe Glen meant, this is what I believe is bothering all of us here. We would like you to do the wrapping automatically. Doing it manually is too much work. Not only that, it is too much stupid work, the work much more suitable for a machine than a human being. Plus, of course, this work is making your code non-portable. Plus, there is a chance that in a couple of years you will have to redo this work. All of this has to deal with C++/CX, not with WinRT.

    Thanks again, keep it coming folks.

  • GlenGlen

    Herb

    I appreciate your candid efforts to explain your thinking to me re: c++/CX.

    I know the problem space is hard - your long wrestlings with it demonstrates that. I hope you will appreciate then, that I and others must climb the same mental mountain as you did, in order to arrive at anything like the same understandings you have; let alone try to reach any of the conclusions you did.

    Infact, it's even harder for me because: a) it's not my job to do it; b) I'm not a language designer and even claim to be a good library designer and c) I don't remotely have the experience, skill or incentive that you have.

    However, in my favour, I am not constrained to support any Microsoft management or technical legacy and I do still possess, for now, a fresh pair of eyes for the problem.

    Most importantly, like the others here with me, I have a vain, idealistic, call it naive if you wish, belief that a better solution for C++ exists than what I see MS proposing so far.

    In that context, I ask you to bare with me and understand that I have no lack of respect for your views even if at the same time I am compelled to challenge C++/CX and WinRT, to either its betterment; its death; or my enlightenment; whichever comes first! :)

    It's just that having wrestled with COM; and to a lesser extent C++/CLI; I'm now being told C++/CX will be the next big thing. However, what I feel is that C++/CLI was a patch to a .NET problem. That that doesn't make it the right solution to model anything on when .NET should never have been created with such a disregard for C++ and when C++/CX doesn't fix any more core issues for the C++ developer than C++/CLI did I fail to see the value in it. Whatever it might do for .NET or Microsoft.

    Herb, C++/CX doesn't change the game enough. COM, C++/CLI and C++/CX all have some terrible things in common. They all make C++ developers manually wrap their own code and they are all have contributed to a lost decade and a decline of C++ on Windows.

    I remain convinced that either a better or different solution must be achieved, if the only other choice is to repeat the wrapping process again and lose yet another decade; or risk further decline of C++. C++/CX needs to be highly transparent. However you do it. Or the model is wrong or the technology is not sufficiently baked. Pick one, but not both.

    MS has a history of half baking things. If COM had continued advancing the first time around to where you have progressed it today, regardless of COM's merits (which is another issue), just look at how much pointless buggy code you would have saved from being written!?

    Do you think at that time people didn't say COM was too hard and not right at the time? Did MS listen then? It took a decade for it to be revisited and look at the wake that left.

    I assert again (perhaps naively) that either things have stopped too soon again and that more needs to be done to make C++/CX and WinRT transparent. Or alternatively, things have gone too far and the model is too complicated.

    None of Microsofts past developments since MFC have done anything but dilute or diminish C++'s viability on Windows and I don't see why I should trust that C++/CX is not more of the same when it doesn't appear to change the game. Until C++/CX becomes transparent (or non existant), I don't know that its too dramatic to say we have a problem that will either bring down C++, or Microsoft, as the force it is today.

    What I do know though is that Microsoft, through COM, C++/CLI and .NET are now C++/CX are doing more to damage to C++ than promote it. I know which side of fence I am on if it comes to it. When you have to fight your customers this much, you should know something is wrong. We do.

    Only time will tell if I am right; but if C++/CX can be made transparent, the size of that prize will be far greater for C++ and C++/CX than even the size of the code MS has already consigned to the dustbin with its COM improvements so far.

    The size of that prize merits the size of the dialogue to find the solution and the great thing about ISO C++ is that we own it. It is our job to fix this situation whatever it takes and we have a workforce the size of the planet to do it.

    I just wish this dialogue had happened before C++/CX or .NET even had started.

    In my next post, I'll spell out the C++/CX wrapping nonsense and everyone can really hammer the truth of what I'm saying.

  • @hsutter:

    You are asking Glen:

    What would you say if you were proposing virtual functions for C, and someone asked, "Why do you recommend getting two notions of functions? Functions are functions, darn it, everyone knows that, virtual functions are just functions and I'm sure you can express them in ISO C without extensions, we have function pointers and everything you need."

    My answer to that would be:

    I am all for making better abstractions, but we have to do this in an organized way. Our language is complex and so if everyone just adds whatever he feels like adding, all benefits from these additions will be erased by the chaos that will arise. Additions have to be vetted so that they extend the language in natural, intuitive ways, so that they don't fight each other, so that there is not too many of them, etc. If you want to add virtual functions, go ahead and suggest this to the standards committee. If they take it on board, and I do think virtual functions are genuinely useful, so I don't see why they wouldn't, great. If they don't, so be it.

    What you are doing with C++/CX is something else. You are putting the cart before the horse, like others said, with properties, events and numerous other things.

  • @Matt:

    Assuming an almost 100% ISO C++ simple and elegant solution for creation and consumption of WinRT objects can be designed (will definitely love that), could it be implemented by a third-party entity (e.g. not Microsoft) or are there some technical limitations?

    The sad thing and the only reason we are having this long discussion on this thread is that the ISO C++ solution as proposed above requires cooperation from the compiler and this is something that is much easier for Microsoft to do than for any third-party. The Microsoft compiler already parses C++ code and extracts WinRT concepts from that code, the only two things Microsoft has to do is make this work for regular C++ code instead of for their extended syntax, and to generate WinRT concepts as both metadata and C++ source code. We can achieve the same using, say, LLVM, but it won't be easy. If it was easy, or if no cooperation from the compiler was required, we wouldn't have had this thread, we'd just do it and use the result.

  • GlenGlen

    C++: "good for writing libraries"
    ---------------------------------

    A stated goal of C++ is to be "good at writing libraries".

    For many developers that definition of "good" means:

    1. reaching the widest practical audience
    2. with the most maintainable and efficient libraries.

    That means not writing repetitive code, being able to achieve the absolute best performance possible without making too many compromises on the code quality or maintenance and being able to reuse pieces of other code whether written in C++ or in other languages and to expose pieces of C++ code for such reuse.

    Conversely:

    If a language doesn't help with following best practice, it creates a maintenance mess and will be challenged by other languages.

    If a language or library doesn't target a wide audience, it consigns itself to a niche role and a small market. Neither reality encourages developers to use such a language.

    If a language doesn't encourage maintainable code, it deminishes its own profitability in whatever market it is in and therefore its own lifetime, such a library and its developer will be overtaken in its market.

    If a language diminishes itself or ignores its core customer base, it risks its own viability and that of the developers using it.

    C++/CX: "good for writing libraries"?
    -------------------------------------

    The goal of "reaching the widest possible audience practical" can only be met by:

    1. supporting other languages
    2. supporting other platforms

    For a language to support being called from other languages, the called language must have its own notion of class described in metadata. If it doesn't, the "other" languages notions of class cannot easily map onto it and the code of the implementing language cannot be called.

    C++/CX chooses not to generate metadata for C++'s own class: the iso class. Rather, it chooses to leave the iso class invisible to other languages and instead, C++/CX augment C++ with a second notion of class: the ref class, for which it does generate metadata.

    Having two notions of class in a language is a rare design and appears to leave the developer and the language at odds with itself:

    Does the language need two class types?
    Does a developer support one, the other, or both?
    What does one "do" in each class type?
    What does it mean if one doesn't do what one expects in either class type?
    How will future ISO committee decisions impact or be impacted by C++/CX?
    Will the ref class and the class ever be reconciled into one and does it need to be?
    What does it mean if it isn't reconciled?

    For an ISO C++ library to become usefully visible to other Microsoft languages and platforms, it inevitably MUST use a ref classes, as its own class is invisible.

    But for a C++ library to support its own customer base, itself, the language itself, and other platforms; it inevitably MUST use iso classes.

    Supporting just ref classes would be to abandon C++. The cross platform viability of even the simplest function would be lost if it were tied to Microsoft by being implemented in a ref class. Even on the same platform, non Microsoft clients would be shut out from using code if this approach were taken. This is bad for C++.

    Supporting just iso classes would be to forgo having ones libraries being easily useable from other Microsoft languages and platforms, like Internet Explorer. This is bad for C++.

    Supporting both class types invites duplicate code and reduces maintainability. ref classes introduce the reality that there are now two choices where to find and implement a function and two ways in which to invoke it and two decisions on what to name it. All of this is to define, reach, and name the same implementation. This is bad for C++.

    The Reality of C++/CX
    ---------------------

    If one wants to avoid duplication, retain consistency and actually even just use C++ at all. The only solution is to have the ref class be simply the delegator to the iso class where the sole implementation must exist.

    The above solution yields:

    * the ability to support being called by Microsoft languages and platforms.
    * the ability for even the most trivial of code bases to not become tied to Microsoft.
    * the ability to retain clarity that one isn't implementing the same thing twice or the same thing differently by mistake.
    * the ability to support ones existing core customer base (C++!) on other platforms and on the same platform!

    Observations
    ------------

    1. Two classes are required to for every one concept or service in the object model.
    2. Both classes work together but they are expected to provide the SAME identical service. If they don't, the object model is duplicitous.
    3. Logically, there is and only should be one implementation of the same service.
    4. Having two classes for the same thing creates ambiguity about what to write where and how to name either.
    5. The two classes that provide the same service should have the same name yet they can't because their class names must be different.
    6. Even if both classes have the same name (through different namespaces), it is inconvenient and exposes two ways to invoke what should be the same implementation of same service.

    Practical Realities / Coding Standards
    --------------------------------------

    1. The ref class MUST be the wrapper because only it exposes the metadata so only it has visibility to receive other language calls "easily".
    2. The iso class MUST be the implementer of the service. Otherwise straight C++ support is lost and the library has become tied to the platform.
    3. The ref class MUST not implement the service, just wrap/delegate to it. Otherwise the object model design becomes ambiguous and the execution duplicitous.
    4. Wrapper and implementer work to provide the same identical service. If each model provided a different service, it would likely be an error.
    5. Both classes should have as similar name as possible and by convention so knowing one yields the other or one is inviting a maintenance headache.

    Conjecture
    ----------

    The ref class is always a "simpler" entity than the ISO class. It's type system is simpler; it's delegation system mechanical; and its implementation should be minimal for reasons given. It is just the delegator.

    The relationship between a ref class and an iso class is likely to be a one to one mapping of classes, functions or parameter types.

    When following the ideal development methodology, ref classes serve no purpose except to be a reception point, translation point, and a delegation point to iso classes. Therefore, in some sense, ref class serves as an abstract iso class.

    Abstractly, directly instantiating a ref class in an ISO context is redundant and therefore ref classes appear to have no strong place in the ISO C++ type system and the name clashes are a nuisance.

    The navigation from a ref class to an ISO class is a mechanical mapping, configuration of that may be of value but the receive, forward, implement relationship remains the same.

    What has been described is just the problems with authoring side. This doesn't begin to discuss the use side. A C++ client would not wish to know anything that would make it aware it was using a non C++ class or a C++/CX one or that would entail more problems.

    Conclusion
    ----------

    C++/CX as it stands introduces significant complexity into C++ and is a competitor to C++. The burden it places on the "straight C++ developer" appears to be one that is detrimental to the C++ language and to the productivity of the developer using it in general and the maintainability of products created in it.

    C++/CX primary issue is that it creates a non transparent "borders everywhere" burden in that it practically requires the C++ developer to manually wrap any iso C++ class that it intends to expose to another language, in its own C++/CX specific notion of class. In reality the C++/CX class must simply delegate to the ISO one to avoid other impairments.

    The model ascribed to C++ by C++/CX is unique in that other languages like C# will not work this way and no two class model is likely to be seen in any other language.

    It is hard to see how this model promotes C++ development. It is unique to "extend" a language by adding a second notion of class, but in this context "replace" seems more apt than "extend".

    Classic COM and C++/CLI where this type of wrapping model have been adopted before resulted in significant diminishment of the C++ language, by forcing significant maintainability and productivity burdens on the developer. Since C++/CX does not change this pattern there is every reason to think it will be the same.

    The model should be scrapped or enhanced to the point where the burden is removed.

  • MortMort

    Interesting, as Herb Sutter explains, the direction received by his team from management was:

    R1. Enable full power and control, including both consumption and authoring.

    R2. Be as simple and elegant as possible for the developer.

    Right from the outset, we see that there was no requirement to conform to the language standard. This alone speaks volumes. Earlier in the thread Charles said that Microsoft cares a lot about standards and someone remarked that the extent of that is before our eyes: C++/CX is a huge pile of non-compliant stuff. The lack of "R3. Comply to the latest language standard." is one more illustration as to how much Microsoft really cares about this.

    Let's also see how the Visual C++ team delivered on the second goal, expanding on it as Herb Sutter does:

    To minimize the amount of non-ISO C++ code the user has to write. FAILED. Using C++/CX immediately makes your code non-ISO C++. As soon as you convert a class to a ref class, you have to convert 'new' to 'ref new', you have to convert pointers to that class to hats, et cetera, C++/CX tries to propagate outwards.

    To not create a disincentive to use (V)C++ on WinRT. FAILED. It is simpler to use C# or Javascript than C++/CX. It probably makes more sense in the long run as well.

    In effect:

    R2. Be as simple and elegant as possible for the developer. Summarily failed.

  • TomasTomas

    @Matt:

    > Assuming an almost 100% ISO C++ simple and elegant solution
    > for creation and consumption of WinRT objects can be designed
    > (will definitely love that), could it be implemented by a
    > third-party entity (e.g. not Microsoft) or are there some
    > technical limitations?

    Well it's not so easy but could be done if few smart guys
    work together. Normaly the most difficult part would be the
    C++ parser but clang is progressing very nicely and should
    handle the job well. Then you have to write the #import
    parser for MS COM interfaces because I don't think clang can
    understand them. But parsing interface definitions (without
    function bodies) is not so difficult. Then there are the
    winmd metadata files. Not sure if the specs are available
    somewhere but if not it's easy to figure them out from
    C++/CX output (they are supposed to be text files)

    After you have the tool done you are no longer forced to buy VS.Next
    - VS2010 compiler or even non-MS compiler would do as well. (but
    VS2008 would not since the generated code will employ WRL which
    uses some C++0x stuff like decltype, nullptr and type traits)

    There are however some minor problems if code generation is done by
    3rd party. For example you cannot use VS XAML editor since it will
    still generate widget declarations and event handlers in C++/CX code.
    Also you have to manualy set up the project to compile and link
    generated source files. So using 3rd would not be so convenient as
    if MS does it itself.

  • I asked: "Before I go further, let me sanity-check something: Do we agree that the route of "extending TLB #import" leads to a full ATL + MIDL like approach?"

    @PFYB answered: "No."

    Then you're clearly mistaken. WinRT is COM (and then some), and in general you can't author COM types without all the additional information about the types you can specify in an IDL file -- whether those information-carrying extensions go into a separate IDL file (the MIDL approach) or into the main .cpp file (the C++/CX approach, though it could be done with different syntax, but it must necessarily be just as rich in order to to the job).

     

    @PFYB: "ATL + MIDL is a reasonable way to write code, but we are talking about something else. We are talking about not only "extending TLB #import" to cover WinRT modules, but also about doing the reverse of #import, that is, parsing regular C++ code ..."

    Again, "regular C++ code" doesn't carry sufficient information.

     

    @PFYB: "...and generating wrapper C++ code in order to expose regular code to WinRT.

    Here is an example:

    // ISO C++
    struct I1 : public IInspectable {
    virtual void F() = 0;
    virtual std::wstring G(int) = 0;
    };
    struct I2 : public I1 {
    virtual winrt_ptr<I1> H() = 0;
    };
    class C : public I2 {
    public:
    C();
    ...
    };"

    Short answer: There's not enough information in that code. Also, this doesn't avoid the need to generate wrappers, you will be generating wrappers anyway such as to change the std::wstring type to HSTRING and change all the function signatures to HRESULT returns and generate code to catch exceptions and translate them to HRESULTs and a dozen more things (I think you know this, but others on this thread think wrappers are unnecessary so I'm noting this for completeness; wrappers are necessary, and the goal above would be to generate the wrappers automatically from the above code).

    To take just the first line, a few problems I can see are:

    • ": public IInspectable" is not really C++ inheritance if you want it to have WinRT semantics.
    • There's not enough information to decide whether the intent is to define I1 as an interface or a class, since a class could be named I1 and could have all pure virtual methods. (I hope you won't suggest a heuristic like 'if it has all pure virtual methods, implicitly assume it's an interface.' I tried that in early C++/CLI, in desperation to stick with ISO C++ even though I knew the heuristic approach was brittle, and it fails spectacularly anyway in several ways that are all ultimately rooted in that the programmer didn't get to express his intent explicitly.) Note that this lack of clarity about whether it's an interface or a class is not a problem in ISO C++ because ISO C++ has no separate concept of an interface -- everything is a class so it's all the same -- but it is a problem for any object model that does distinguish the two and has to generate significantly different code and semantics depending on which it is.
    • As I've said before, the code doesn't carry enough information to generate metadata, do code generation, etc. The user still needs to provide all that information somewhere.
    • As for the rest of I1, note that I1::G that returns a std::wstring will be slow if you provide only that much information. You can't actually use a native wstring on the boundary (it's not ABI-safe) so you will at minimum have to automatically convert it to be a WinRT HSTRING instead, and then how will you generate the code so that you don't do a needless conversion and temporary value on every call (if you say that last one is easy, I think you don't understand the problem -- performance will generally be unacceptable if you create a new HSTRING on every call to I1::G)?

    Similarly, in the other two cases with the pattern "class X : public Y":

    • Again, there's not enough information to do WinRT code generation. For example:
      • We don't know whether each of X and Y is intended to be a class or an interface.
      • WinRT requires X to have a default interface, but there's nothing in the code that says whether Y is to be the default interface for X. We could assume it must be, but then when you have "class X : public Y, public Z" how do you specify which interface should be the default interface? The user has to be able to state that information somewhere, and lots of other information like it.
    • The meaning and code generation is completely different depending on whether each of X and Y is intended to be an interface or a class. There are three possible legal combinations, and all of them have very different code generation.
      • If X and Y both are interfaces, we have to emit a requires relationship and every cast must QI.
      • If X is a class and Y is an interface, we have to implement the interface, which is not as easy as it sounds because it then further depends whether I1 is to be the default interface or not:
        • If Y is the default interface, we can inherit directly, and every cast can just do a normal derived-to-base conversion. (We could just QI all the time, but that would be slow and a good example of the kind of pessimization you get when you don't have enough information.)
        • If it isn't, we can't and have to use a different representation.
      • If X and Y and both classes, we have to implement a complex COM aggregation-like pattern with a bunch of helper interfaces.

    So where exactly is the syntax that lets the user state whether X is intended to be a class or an interface? what its default interface is? whether to actually inherit and do pointer conversions under the covers or emit a requires relationship into metadata and QI all the time? whether to aggregate the FTM (free threaded marshaler)? and a dozen more things like that.

    Disclaimer: This is just scratching the surface. It is not by any means a complete list.

    By the way, as I mentioned last night, I tried exactly this approach early in the C++/CLI effort -- there, ": public IInspectable" was spelled ": System::Object". Quoting myself: "For example, I asked "why do we need a new class category, why doesn't it just work to have 'class X : System::Object' be an inheritance tag from a magic type that the compiler can treat specially?" and spent several weeks trying to make it work, and several dozen similar questions -- many similar to questions in this thread."

     

    @PFYB: "I hope the above is sufficiently clear."

    I do understand what you want. I was in the same place in 2004 and tried many variations on this theme, and then we tried it again in 2010-11 in case WinRT might have removed enough of the constraints we had with .NET so as to make it possible (it didn't).

     

    I think it's clear that we aren't going to be successful designing this together in a comment thread, and if you refuse to accept that it isn't that simple, from the people who tried and understand the requirements and constraints deeply, then the only alternative is for you to invest the time to make the technical effort yourself -- not just sketch things that look plausible, but build the prototype (including correct and complete binding to WinRT features and high-quality VS product tooling integration) and demonstrate a proof of concept.

    This isn't science, it's engineering. There are many plausible ideas, but the only proof that an idea works is to show working code. As you do the exercise, you will discover a number of constraints and problems.

    But sometimes the only way to explore is to go into the wilderness in person to see for oneself, if one won't accept maps from people who've been before. And that person on his own trek may indeed find something new that the earlier explorers overlooked -- that's how we make progress -- but one won't know until he actually goes, one can't decide that by the Victorian method of making a pencil-and-paper sketch sitting in the living room armchair by the fireplace.

  • I asked:

    "consider:

    ref class Screen {
    public:
        int DrawLine( Point x, Point y );
    };

    ...

    What is the minimal code syntax and build steps it would it take to express this in a MIDL-style approach, and across how many source/intermediate files? What's the best we could do in that kind of alternative approach?"

     

    @PFYB answered: "For the sake of completeness:

    // ISO C++
    class Screen {
    public:
    int DrawLine( Point x, Point y );
    };"

    If that's your answer, you didn't understand the question.

    Let me try to explain, at least with a few basic examples, why I don't think the above begins to answer the question because there's just not enough information:

    • Is Screen is supposed to be a WinRT class, not a C++ class? How does the compiler know? How do I say so?
    • Should it publicly inherit IInspectable, or not? (Your answers are inconsistent -- in your first example you show inheritance from IInspectable, whereas here you don't.)
    • What is the Screen type's accessibility -- public or private? How do I say so?
    • Does Screen aggregate the FTM? How do I say so?
    • ... lots more but that's a start ...

    You also didn't answer "what... build steps it would take" -- what are the build steps and tools involved, in what order are they invoked, and what does each one do? Also, "and across how many source/intermediate files" -- I think your answer to the source is no more source files, but what about intermediate files?

    I'm just trying to explain why the above doesn't begin to answer my question. To me this isn't an alternative design, it's writing plain C++ code and waving "do the right thing to make it work" hands.

  • CharlesCharles Welcome Change

    @Mort: You are oversimplifying the problem. You make it sound like crafting an ISO C++ solution to this WinRT-specified set of constraints is simply just an option, one that is no more complicated to implement effectively/efficiently/effortlessly - adhering to the underlying platform's object model and runtime environment rules - than a small language extension. Did you read what Herb wrote? What Jim wrote?

    @Everyone:

    I get the sense that many of you just don't want ANY answers that aren't "Yes, you're right, we should have implemented support for WinRT's object model and runtime enviroment in an ISO C++ solution and never seriously considered the benefits of a small, platform-specific (WinRT) language extension for simplying the expression of developer intent when programming shared, ref-counted COM objects in a new hetrogeneous programming model for Metro style application development on Windows 8".

    You're not going to get that answer. If nothing else, then please accept this fact. C++/CX is real, not imaginary or speculative like the reverse of #import with wrapper classes solution.

    One of the clearly stated goals for VC++ for Metro Style Apps - and the one that is consistently ignored on this thread - was to make playing in the WinRT sandbox easy for C++ developers, too (and let's not forget the tooling side of the equations, VC++, as Herb articulated clearly...). I wonder what your response would be if you were handed only WRL and this imaginary/speculative "reverse of #import with C++ wrappers" solution. What would the tools look like? The experience in VC++? Your workflow? Open questions, of course. But, there are more questions than answers here. Solutions are presented without defining, clearly, the question. What's the question?

    Herb has spent a great deal of time on this thread. Thank you Herb. And thank you Jim. I think it's time to let him go and re-read what he has written, if need be. He's got a few other things to do. One of them is shipping C++/CX in VC11, which is going to ship. That ship has sailed. It left the harbor at BUILD.

    The VC team is well aware that much better WRL documentation is needed and more samples that clearly demonstrate what they mean by C++/CX "boundary" layer programming with most of your code being ISO C++. It's understood. Message received. You're right.

    WinRT (COM) defines the model, not C++. Ease-of-use was a key factor in the design decision at play here for C++/CX. You don't lose performance and control, but are afforded a simple high level abstraction for programming in an ABI-safe, ref-counted, multi-language/runtime-supported, COM world that IS WinRT. If this isn't clear by now, then I don't know what else can be said to make it clearer.

    Look, I for one (and I speak for myself only - myself only) think it's unfortunate that of all languages that can be used to program WinRT apps, C++ was the only one that was extended. That said, based on I what I now know from this thread and from conversations with Herb and the VC team, there really was no other practical choice, one that met the bar for ease of use and COM friendly. Herb and Jim are not lying to us... They speak only the truth (they are the ones who discovered the truth in this case...) and we all should respect this and accept the fact that C++/CX isn't going away. It's already here. Personally, I think if you play around with it for a while, it starts to feel more natural - and this is why I said "it's just hats and refs, man". I know that might have come across as me belittling the issue - my apologies for that.

    Thanks, as always, for speaking your minds and listening, learning, questioning, listening, learning, questioning. At this point, we really should (all of us, including me) respect Herb and Jim's time. This doesn't mean you aren't free to continue the discussion ( I'm sure you are going to blow up my reply - that's OK. Smiley ). Just don't expect Herb and Jim to answer your questions soon after you post them. Let them work, OK?

    C

  • @Mort: "Interesting, as Herb Sutter explains, the direction received by his team from management was: R1. Enable full power and control, including both consumption and authoring. R2. Be as simple and elegant as possible for the developer. Right from the outset, we see that there was no requirement to conform to the language standard."

    Because that's so obvious it goes without saying. As I continued (and you then quoted) a key goal of our management and my design team was, and the boldface is in the original: "Minimize the actual amount of non-portable non-ISO C++ code/tools developers have to write/use to use WinRT." You can call it failed, that's your prerogative, but it's disingenuous above to declare that I said we didn't have it as a goal -- it was one of the three I boldfaced.

     

    Here's a clear counterexample: Look at C++ AMP. The same management and same design team in the same product cycle did a complete extension of C++ for GPGPU programming as almost a pure C++ library that follows C++ STL conventions faithfully and relies on C++11 features like lambdas -- with only a single language extension because one was necessary. We'd have been happy to do it without any language extensions, but that's not possible because current GPUs cannot handle the entire C++ language -- nevertheless, even with some extensions necessary, we're very proud of having been able to find a single general extension that enabled the rest of it to be written as a library.

    There is not another GPGPU product for C++ out there in the marketplace today that does it with as few language extensions to ISO C++ as we did in C++ AMP in this same product cycle -- just one extension, the rest as a pure library. If you want to draw any conclusions from that, it would be fair to say that in the GPGPU space Microsoft values C++ more than any other company (all others primarily target C99 dialects, with at best C++ wrapper libraries) and placed higher priority on ISO C++ compatibility and minimizing language extensions than any other major GPGU vendor (they all have way more language extensions).

  • GarfieldGarfield

    @Herb Sutter: Thanks for interesting posts. Now, two things come to mind after reading your "confessions".
    First, WinRT isn't really suitable to be exposed to C++; the model is too foreign to C++ even in CX garb. WinRT and C# are twins, which will never happen to C++, because it would require C++ to become C# with different syntax (C++/CX), but that will simply move the tension to the boundary with C++ uncomfortable with what is one side and WinRT (C#,CX) uncomfortable with the other.
    Look at this example, how verbose and foreign to C++ it is: "Getting data into an app"
    http://msdn.microsoft.com/en-us/library/windows/apps/br211380(v=VS.85).aspx#getting_data_into_an_app
    I'm not that much concerned with language extensions like properties, delegates, etc. as they are confined to the class. But I'm very concerned with foreign types and hats that will bleed outside and I don't see other alternative than a fence of native types to stop it. I’m assuming everybody agrees that WinRT types and hats have no sense in C++ applications and must be stopped at the boundary.
    Secondly, the same solution coming back to me: don't expose the foreign WinRT types to the C++ applications. Instead create a C++ library with standard types, albeit with property and delegate extensions, but use WinRT types only as underlying implementation, don’t leak them to interfaces. If that limits C++ designs to consumption only, so be it, 99% of developers will be happy, and the other 1% may decide to suffer through CX.
    P.S. By the way I liked what I learned about AMP from the presentations, and language extension didn’t bother me at all. But C++/CX is a completely different matter, it’s not just language extensions, it’s a conceptually foreign model with conceptually foreign types.

  • GlenGlen

    @Herb, you said:

    "I think it's clear that we aren't going to be successful designing this together in a comment thread, and if you refuse to accept that it isn't that simple, from the people who tried and understand the requirements and constraints deeply, then the only alternative is for you to invest the time to make the technical effort yourself "

    Herb, as I've said to Charles before, I agree we aren't going to get an answer easily or quickly. I've also said flat out "we aren't ready for you yet", we'll likely waste your time until we're ready with the right questions.

    I also agree that it will take exactly the kind of victorian efforts to get an answer.

    However, this "design by thread" is of value. It's the only way the rest of us can quickly get the kind of information we need out there.

    Yes it's not so much (arguably any) value for you, yet. But the rest of exactly do "need to design this together in a comment thread".

    I have never thought anything other than that. Of course I'm pleased you are reading it. Just don't burn yourself out because we will need and expect you later.

    You should be checking in though, as you are, as should everyone in MS development - to take notes of what is bubbling on the minds of the people here. That's the main value for now.

    But doing this "design by thread" is really of value for the rest of us. It's the only way to for the "common people" to get together to get enough "common knowledge" out there quickly.

    Common knowledge in this sense doesn't mean it's right, tasteful, informed or anything.

    It's just a dialogue we need to get "out there" to get people together and contribute their common wisdom, goals, concerns, understandings, rants, whatever, together to hopefully (eventually) to do some common good. Sorry that it doesn't read well until then.

    It definitely has value. It's the only way of illuminating this space and start something. I know its frustrating for you to see us where you were 12 months ago, but try to be optimistic. That's what grass roots and idealism is.

    We aren't sold on WinRT and C++/CX and COM as it stands, this will help you see why. We want to proove to ourselves if our hunch is right. To do that we have to struggle to "fix it" or to define something better. We might fail, give up, or whatever.

    But we don't have the same constraints you had, our goals aren't necessarily yours or Microsofts, so we might get different answers.

    This thread is most certainly of value though. We need it to illuminate and find consensus on this subject. I believe this is the best way to do it and that it is working.

    Wish us luck.

  • GlenGlen

    @Charles, you said:

    "I get the sense that many of you just don't want ANY answers that aren't "Yes, you're right, we should have implemented support for WinRT's object model and runtime enviroment in an ISO C++ solution and never seriously considered the benefits of a small, platform-specific (WinRT) language extension for simplying the expression of developer intent when programming shared, ref-counted COM objects in a new hetrogeneous programming model for Metro style application development on Windows 8".

    You're not going to get that answer. If nothing else, then please accept this fact. C++/CX is real, not imaginary or speculative like the reverse of #import with wrapper classes solution."

    Charles, you have a gift.

    Microsoft can consider what ever they like. But have you ever considered that customers don't have to buy it nor do they have to meekly lie down and accept your "constraints" as "their" constraints?

    Watch the fur fly with that attitude.

  • GlenGlen

    I don't see how adding a second class to a language is a "small extension" either.

    If I came and built my house on your back lawn next to your house and called that a small extension too, what would you say?

  • CharlesCharles Welcome Change

    @Glen:



    Microsoft can consider what ever they like. But have you ever considered that customers don't have to buy it nor do they have to meekly lie down and accept your "constraints" as "their" constraints?

    Watch the fur fly with that attitude.

    I fully agree with this sentiment. I am not suggesting that "you take it like a man", but rather "it is what it is". There's a difference. I'm all for this conversation continuing - just as I said in the post you've quoted from. I only asked that we all respect Herb and Jim's time - which is squarely focused on shipping VC11 (and this includes C++/CX, the WinRT-only C++ extension).

    I love this conversation and the degree to which you have all poured your hearts, minds and time into making something meaningful out of this dialog. Thank you.
    C

  • CharlesCharles Welcome Change

    @Glen:

    I don't see how adding a second class to a language is a "small extension" either.

    If I came and built my house on your back lawn next to your house and called that a small extension too, what would you say?

    I don't think this analogy quite works in this specific case, but I respect your position and I understand what you're trying to say. I can't argue with you.

    C

  • My adoption decision depends on:

    1) Better documentation on how to use the combination of XAML, WinRT and C++/CX. 

    2) Platform targets. My current belief is that the Windows phones will never allow C++, tablets will be Win 8, and WinRT won't apply to the installed base of Windows 7 computers.

     

     

  • C64C64

    PFYB wrote

    We can discuss how to do the translation for delegates, events and everything else. This is a lot to talk about, but from what we see, for every feature a regular C++ mapping of concepts can be done.

    Just like "for every C++ feature a regular C mapping of concepts can be done" (see for example the excellent example Herb made for virtual functions, or the article I pointed at the beginning of the thread on writing COM components in pure C). The point is: how this mapping is implemented? How is the quality of the resulting code?

    Sometimes you have to raise the semantic level of code, and if this can only be done with language extensions, what's wrong with that? "Language extensions" to C (like the introduction of "class" keyword, "virtual" keyword, etc.) gave us C++. You can write OO code in pure C, as you can write COM components in C, but this requires a lot of work.

    And "language extensions" to C++03 gave use C++11: e.g. you can have functors in C++03, but - at least for simple functors - I think C++11 lambdas are more convenient (for more complex stuff, good old classes with operator() overload can be better suited).

    A. What is the minimal code syntax and build steps it would it take to express this in a MIDL-style approach, and across how many source/intermediate files? What's the best we could do in that kind of alternative approach?

    For the sake of completeness:

    // ISO C++
    class Screen {
    public:
    int DrawLine( Point x, Point y );
    };
    Screen s;
    s.DrawLine( Point(10,40), Point(20,50) );

    There must be a way to tell the compiler that "Screen" is a WinRT class.

    The C++/CX way of doing so is the "ref" before "class". Is "ref class" much worse than say "class __declspec(winrt_export) Screen { ..." ? I'm not sure it is. (Frankly, when writing Windows C++ code, I used "throw()" as a way to tell MSVC compiler that a method doesn't throw, instead of the more verbose "__declspec(nothrow)"...)

    And about instantiating Screen "on the stack" with the "Screen s;" statement, well WinRT classes have more complex creation semantics. There are blog posts that show how an apparently simple C++/CX syntax is actually equivalent to several steps:

    auto app = ref new App();app->Application::Run();

    The equivalent "pure C++" code is something like:

    const wchar_t *appClassName = L"Windows.UI.Xaml.Application";HSTRING hstring;hr = ::WindowsCreateString(appClassName,static_cast<UINT32>(::wcslen(appClassName)), &hstring);CheckHresult(hr, L"WindowsCreateString"); IInspectable* pInspApp;hr = ::RoActivateInstance(hstring, &pInspApp);CheckHresult(hr, L"RoActivateInstance");::WindowsDeleteString(hstring);CheckHresult(hr, L"WindowsDeleteString");

    In this case, I welcome a language extension that makes my programming life easier (note that the above blog contains other more complex examples).

    Note that if I'm targeting WinRT and Metro I'm already out of the "cross platform" kingdom, so it's not particular important to me if there is some non-standard non-portable language extension in this particular context (some pure C++ class like say winrt_event<...> would be equally non-standard and non-portable).

    As a side note, I don't have experience in designing programming languages and implementing compilers, I'm just an "user" (as a C++ programmer) of programming languages and compilers. I think we can trust people in VC++ Team if they say they tried first without extending the C++ language, but it was not a good experience for the "end user" programmer, and they figured out C++/CX was a more productive tool for us.

    However, it would be interesting if you and other guys could start an effort to try to offer a "pure C++ no-extension" approach to solve this problem of WinRT programming from C++, and let us know here. As I said, I'm open minded, I've a practical view of programming (I don't like "religious wars" in programming), and if you prove that you can do in pure C++ what can be done in C++/CX with a good level of productivity, that's good. But you have to build something concrete to convince me, not speculate on possibility to do X in this way, Y in this other way, etc.: just try to write some concrete code and tools, some concrete prototypes, and see what happens. Win 8 Dev Preview and VS2011 Dev Preivew are already available for download on MSDN. I'm curious.

    Moreover, I'd like to say thank you to everyone who participated in this thread and spent his precious time writing insightful posts here, from PFYB to Jim Springfield and Herb Sutter, etc. I learned a lot!

    Charles: it would be great if you could do another C9 episode on C++/CX with Jim Springfield (who is also the inventor of ATL - after several years, the best tool available today IMHO to do COM programming in C++), Herb Sutter and maybe invite also the great Larry Osterman (I recall some old pre-Windows 7 video of him), who seems to be working no more on the Audio team but instead on the WinRT team, so we can have both the VC++ Team point of view and also the Windows point of view.

    Thanks.

  • GlenGlen

    @Charles

    "it is what it is"

    That would be fine if "what it is" was clearly understood, static, or finished AND if it were also the case that most people agreed that whatever "it" is was necessary or beyond significant improvement.

    None of that is agreed. Clearly there is support for the endeavor to challenge C++/CX and WinRT to proove itself and to illuminate it in general.

    Even if C++/CX were "done" according to Microsoft, that wouldn't mean anything to me on its own without a clear idea about what exactly what is done and how right it is and a community consenus if we should we buy into it.


    And what exactly doesn't work in my house analogy? I could go further:

    What if someone didn't just build a house on your own back lawn next to your own house and tell you its "small". What if they did more than that:

    What if they hammered out a large house in private, without warning you, over the course of a few years, THEN plonked that on your lawn and told you it was just "small". Then what if they actually first tried to pass it off as just really being your own house too!?

    Then what if they started telling you it is in your interest to have two houses on your lawn, one that you don't own, and that exists without a design rationale, code of compliance, or a council permit for its construction. What then if they proceded to get frustrated with you for not agree to why any of it was necessary!!

    By all means you or anyone else, argue, pick fault with that analogy if you wish.

    Anyway, while I'm here, I'll repeat something else, I remain totally open to language extensions, possibly many. I may even propose some myself, who knows.

    I will totally support those who can justify not having them too.

    Job 1 is to extract the core of what it is about COM that makes COM sooo necessary. Is it? And for who?

    Job 2 is to figure out what language extensions (if any) enable us to use what is necessary, easily without requiring complete destruction of our existing code models.

    Job 3 is to build a consensus on all of that.

    Job 4 is to determine if what we come up with is actually good for C++ or C++ developers, regardless and how that improves on or not, against what Microsoft has already come up with and what it means in the big picture.

    To answer your earlier statement, you're right that if that doesn't stack up for me, and C++ shouldn't do it, can't do it, or be made to support it without burdening the C++ developer with any more work than anybody else has, then I likely will firm to the idea that the object model is wrong, or its bad for C++, and that we don't adopt it. So far, thats where I'm at, actually, and trying to work back.

    I believe that anything that fundamentally subverts the class concept in C++ in the way that C++/CX does, is bad for the language unless it can be done virtually transparently and/or is done through an WG21 standard.

    I am focused that the wrapping burden be removed beyond any other issue. I am open to language extensions that achieve that. However adding any language extension that rises to the level of actually being a class, as is currently planned, is a whole other ball game. I believe that if such an entity is needed, it is likely to be buried as much as is possible if it is necessary at all.

    I fail to see two "first class notions of class" ever being reconciled by WG21. The ref class has to go or be made transparent such that it is as good as gone.

    Having two classes surfaced in a language is just too big of a jump for me to accept as "small". Frankly, I think you are crazy to suggest that its small, even if we can justify it to be necessary!

    Maybe it'll take Bjarne's personal endorsement of C++/CX in clear specifics to steer me to some other perspective. If this debate achieves that much, that is good. Though I don't expect that and there maybe value to even him for this conversation to run its course.

  • Here are a few quotes I like, from the last messages:

    Charles: The VC team is well aware that much better WRL documentation is needed and more samples that clearly demonstrate what they mean by C++/CX "boundary" layer programming with most of your code being ISO C++.

    Yes please...

    Charles:  I for one (and I speak for myself only - myself only) think it's unfortunate that of all languages that can be used to program WinRT apps, C++ was the only one that was extended.

    I couldn't agree more on this one.

    Garfield: WinRT isn't really suitable to be exposed to C++; the model is too foreign to C++ even in CX garb. WinRT and C# are twins, which will never happen to C++, because it would require C++ to become C# with different syntax (C++/CX), but that will simply move the tension to the boundary with C++ uncomfortable with what is one side and WinRT (C#,CX) uncomfortable with the other. 

    WinRT is COM Sad

    Garfield: But I'm very concerned with foreign types and hats that will bleed outside and I don't see other alternative than a fence of native types to stop it. I'm assuming everybody agrees that WinRT types and hats have no sense in C++ applications and must be stopped at the boundary.

    AFAIK, this is really not easy to do, and to do it right. It is very easy to misuse WinRT types and, for example, call IVector::GetAt(), which issues a COM call.

    Jim Springfield: We believe C++/CX provides value and we are committed to it, but customers can always choose not to use it.  We want to make it the best we can, but at some point the marketplace is the true decider.

    Thanks for providing insight on the story of C++/CX.

  • CharlesCharles Welcome Change

    @Glen: As I said, I can't really argue with you. I understand and respect your position - it's your right to express yourself freely here. Keep it up.

    I want to be very clear - I didn't say anything is "done". I said it is what it is (where is is, well, is). When I interview Jim, I'll ask him if C++/CX is "done". I don't speak for him or Herb or anybody else that does the real work of providing great native tools for C++ developers. Now that that is out of the way...

    I don't think your house building analogy works. I say this because I don't feel the extension is equivalent to you building a house in my backyard without my permission... That seems over-the-top to me. It also contradicts your assertion that you're fine with extensions in theory or in general.

    That said, as I said, I respect your position here - it makes sense to me that you feel the way you do. A solution to a problem was put forth and you don't like it or you're not convinced it was really necessary.

    C

  • CharlesCharles Welcome Change

    @pierremf: I wish you would have completed my thought. Here, I'll do it:


    Look, I for one (and I speak for myself only - myself only) think it's unfortunate that of all languages that can be used to program WinRT apps, C++ was the only one that was extended. That said, based on I what I now know from this thread and from conversations with Herb and the VC team, there really was no other practical choice, one that met the bar for ease of use and COM friendly.

    C

  • GlenGlen

    @Charles, you said:

    "I don't think your house building analogy works. I say this because I don't feel the extension is equivalent to you building a house in my backyard without my permission... That seems over-the-top to me. It also contradicts your assertion that you're fine with extensions in theory or in general."

    I don't see anything contradictory in what I said.

    I objected to the language having two notions of "class" surfaced deeply where that deepness requires heavy wrapping requirement.

    Just because I am open to language extensions, that doesn't mean I am open to any. But nor does that mean I am objecting to all.

    Hence, I have not batted an eyelid at "partial" for example, nor did I object to override or enum class in the past. I saw value.

    If you read my post you'd even see I went out of my way to especially call out the exception which is class and explain the class specific case where even then I was open to if it could be seen to work without a burden and so far I can't.

    Nothing contradictory all all. I don't know what you are talking about.

    How about you explain why adding another class is "small". If it makes your job easier, try to imagine something bigger.

    Go for it, your time starts now! I'm deadly serious funny guy! That should be an easy challenge.

  • CharlesCharles Welcome Change

    @Glen: So, you want to argue, eh? Smiley

    I just don't think adding ref class is such a tremendous burden as to give rise to the analogy of building a house in my backyard without my permission. If that were to happen to me, you can bet that your structure would stand for only so long... Smiley 

    I just see the value in making it easier for me to build a new structure that satisfies the new requirements of a new model for building new structures in my neighborhood. COM evolves, man. Like everything else.

    Now, arguably (that's what we're doing, right?), that's not a very good analogy, but I'm not as smart as you are, Glen. As I said, I respect your position and have not said you're right or wrong. It is what it is, in fact. You are entitled to your opinion and position on the matter. You shouldn't spend much more time arguing with me - there's smarter people for you to engage on this thread.

    I don't think designing language component extensions that make it easier for C++ to plug into foreign object models is such a terrible thing. That's just my opinion. Of course, as I've been quoted, I also think it's a really hard decision to make (extending a standard language to suit a specific platform) and in some ways, in the ideal, it's unfortunate, but I am totally confident in the people who made the call. Most positively. For sure. I trust Herb and Jim and Marian. I trust the VC team. These are exceptionally talented people.

    I can't talk about the details of the underlying foreign (with respect to C++) object model at play here (WinRT). You'll need to watch the BUILD presentations I already linked to or read the MSDN documentation. If you haven't done this, then please do so. Then, come back and see if the color has changed.

    To end this particular tangent (Glen versus Charles object-oriented analogy death match): OK. You're right. I'm wrong. Now, back to the regularly scheduled program.

    C

  • GlenGlen

    @C64, good to see you here, thanks for your contributions too.

    @C64/@PFYB and anyone.

    If you get time, look for my ' C++: "good for writing libraries" ' post.

    I posted some opinions in that particular post that sum up what i think C++/CX means to a typical C++ code base and how using it potentially makes everything microsoft specific unless you take extensive steps to avoid that; and why I actually think you must take such steps, but that to do so will be a massive burden to you and will dimish the value of ISO C++ if that burden isn't reduced.

    It documents my core understanding of what doing a big project in C++/CX would mean to any code base and how I'd likely structure my code in that reality and why I wouldn't want to be burdened with that effort required to do that in the way I actually currently think it currently requires.

    My perspective is that, C++/CX as currently defined, is a burden and C++/CX is not good for C++.

    My further perspective is that it may be possible to make the wrapping purpose significantly more transparent and that the win for removing that would be huge IF it were possible.

    If it were, it would:

    a) significanly reduce the amount of wrapping code required by a magnitude

    b) return the ISO class to prominance.

    c) not dimish the C++ code base or language.

    d) likely require (possibly many) language extensions but if most of them weren't needed all of the time or were attributes and if it did a), b) and c) it might be worth it.

    To that end, I am busy trying to think of what kind of language extensions would do that and then trying to decide how WG21 friendly they'd likely be.

    I'd love opinions on it and especially I'd like to know if people agree on how one would have to structure an existing code base to support both ISO and ref classes as they currently are defined, to support a situation where you wanted code a) to be used on other C++ platforms (just trival non platform specific code), and b) also wanted to expose the class to other languages and c) also wanted to expose C++ classes to other users even on the Microsoft platform who weren't wanting to be exposed to C++/CX themselves.

    Hope that is clear as mud! lol

    Thanks

  • GlenGlen

    @Charles

    I'm really not spoiling for a fight nor trying to be clever but it is just tough when someone says this is a "small" thing but then you can't come up with an even bigger thing than the thing you are claiming as small or non tremendous.

    I don't doubt that herb has come up with some really masterful stuff, nobody rates him higher than I do.

    I can see his work will save large COM projects zillions of lines of code. The biggest COM shop in the world is MS. I can see how this all might be good for you (MS)! Just not me!

    What I want you to understand is that there are many many many "shops" out there that just aren't in a COM world yet and having done some COM projects I would never take them down that road.

    I can however see huge value in being able to expose C++ classes to other languages. But going for that is hard when:

    50% (I'm making that up, but its a lot) of a COM'ified code base is just just forwarding noise. It decimates a code base if it has to wrap itself. I contend C++ has to or it strangles itself. C# just doesn't do this. Which are you going to use?

    But this language extension is so big. I can't imagine anything bigger myself!

    C++/CX encourages and incentivises C++ to go COM. If enough go there, everyone has to go there with the effect being what I said in previous posts.

    If COM is of that much value, WG21 should be able to see it and try to absorb it/make it easier. If they can't, the road has forked for ever.

    No other language that I can imagine will divide itself in this way. This might make C++ uniquely brilliant or uniquely dumb. I don't know yet.

    But I must be really missing a trick here if this wrapping thing is even half as easy (i.e. not so tremendous) as you think.

    If you or anyone cares to explain to me why it's not so tremendous, I'm listening. C++/CLI was no better in this regard.

    I'm not a wiz at language design or library design either, that's why I'm soliciting other peoples opinions and challenging you and opening myself up to the same.

  • CharlesCharles Welcome Change



    C++/CX encourages and incentivises C++ to go COM.


    Close. I would rewrite your sentence to read WinRT encourages and incentivises C++ to go C++/CX.


    If COM is of that much value..

    .

    See above.


    No other language that I can imagine will divide itself in this way. This might make C++ uniquely brilliant or uniquely dumb. I don't know yet.


    Herb addressed this point. C++ is not infinitely general purpose. No language is. See his point, again, on C++ and foreign object models.


    But I must be really missing a trick here if this wrapping thing is even half as easy (i.e. not so tremendous) as you think.


    Both Herb and Jim stated that the net complexity (while also faced by the folks implementing such a solution) would be passed along to the end user programmer, like you. C++/CX, big or small, makes things easier for you.


    I'm not a wiz at language design or library design either, that's why I'm soliciting other peoples opinions and challenging you and opening myself up to the same.


    Both Herb and Jim certainly are.
    C

  • @C64:

    The point is: how this mapping is implemented? How is the quality of the resulting code?

    I agree. That was the original reason for the discussion.

    There must be a way to tell the compiler that "Screen" is a WinRT class.

    I agree. As I said earlier: "There are many different ways to direct the compiler to do this (pragmas, __declspec, predefined bases, separate command line switches, etc), we can talk about pros and cons of each."

    Is "ref class" much worse than say "class __declspec(winrt_export) Screen { ..." ? I'm not sure it is.

    If "ref" strictly before the declaration of a class was all C++/CX was adding, that might have been fine. But, no, we have hats, ref new, generics and everything else. I completely agree we have to talk about what exact code should be written in each case. __declspec is one way for the above, #pragma export(winrt) .. #pragma export would be another. That we have to talk specifically about each case does not mean it can't be done or is even terribly difficult to do. If you are skeptical about that and are willing to take Herb's word that this is terribly difficult, almost impossible, fine, but please realize that this turns it into a talk about faith-like concepts, not about technology. Yes, it is a pity I don't have a complete technical specification ready, I wish I would have one.

    I think we can trust people in VC++ Team if they say they tried first without extending the C++ language, but it was not a good experience for the "end user" programmer, and they figured out C++/CX was a more productive tool for us.

    Why does this have to be about faith? If there are technical arguments as to why not do wrappers, why not present them? Please forgive me for being blunt, but it very much looks like the team made a mistake in not going far enough with C++ and Herb is trying to justify that mistake by any means possible. So many posts from Herb with nothing resembling a counterpoint besides "it's so difficult, you don't even understand", this has to mean something.

    However, it would be interesting if you and other guys could start an effort to try to offer a "pure C++ no-extension" approach to solve this problem of WinRT programming from C++, and let us know here. .. you have to build something concrete to convince me, ...

    Fair enough.

    As said, the approach suggested above requires extending an existing compiler. This isn't easy. Right now, the effort does not seem to be worth it, there is no hurry to use WinRT and if you absolutely have to use it, there are .NET languages and Javascript.

  • @hsutter:

    Do we agree that the route of "extending TLB #import" leads to a full ATL + MIDL like approach? ----- "No." ----- Then you're clearly mistaken. WinRT is COM (and then some), and in general you can't author COM types without all the additional information about the types you can specify in an IDL file -- whether those information-carrying extensions go into a separate IDL file (the MIDL approach) or into the main .cpp file (the C++/CX approach, though it could be done with different syntax, but it must necessarily be just as rich in order to to the job).

    This is just word games. Yes, COM types are different from C++ types and there is more than one way to define the way C++ concepts translate to COM. Yes, we might have to convey some information to whoever is going to do the translation. No, you don't have to use MIDL. That's why I answered "No" above. If you think I should have answered "Yes", because using C++ is similar to using MIDL as long as both are used to define interfaces for COM, good.

    Also, this doesn't avoid the need to generate wrappers, you will be generating wrappers anyway such as to change the std::wstring type to HSTRING and change all the function signatures to HRESULT returns and generate code to catch exceptions and translate them to HRESULTs and a dozen more things ...

    Yes, it is necessary to generate wrappers. Our entire proposal is that you generate wrapper C++ code. That wrapper C++ code should wrap WinRT strings. What is your point here?

    ": public IInspectable" is not really C++ inheritance if you want it to have WinRT semantics.

    We want interfaces to inherit from each other in the C++ way in the C++ code. We want them to do what's required for WinRT in wrapper code you generate. What is so difficult? Why do we have to go through this over and over?

    There's not enough information to decide whether the intent is to define I1 as an interface or a class, since a class could be named I1 and could have all pure virtual methods.

    Agree. This is something to talk about. Nothing too complex, but there are many possible solutions and we have to settle on one. Anything else?

    As I've said before, the code doesn't carry enough information to generate metadata, do code generation, etc.

    That's just you repeating yourself. Please say something specific.

    As for the rest of I1, note that I1::G that returns a std::wstring will be slow if you provide only that much information.

    See my reply to Jim Springfield which explains how you can avoid conversions between HSTRING and std::wstring.

    We don't know whether each of X and Y is intended to be a class or an interface.

    Yes, you have talked about this already. Again, this is something to talk about. There are many ways to go, we just have to settle on something.

    WinRT requires X to have a default interface, but there's nothing in the code that says whether Y is to be the default interface for X. We could assume it must be, but then when you have "class X : public Y, public Z" how do you specify which interface should be the default interface?

    Yes, this is something to talk about. Many ways to go again.

    This is just scratching the surface. It is not by any means a complete list.

    Of course. Nothing impossible or even really difficult though. A fair work, the kind you did for C++/CX, the kind we do day in and day out on our jobs. Nothing trivial, but nothing really difficult either. You just wake up, brush your teeth, drive to the office, get into the chair and do it.

    I think it's clear that we aren't going to be successful designing this together in a comment thread, and if you refuse to accept that it isn't that simple, from the people who tried and understand the requirements and constraints deeply, then the only alternative is for you to invest the time to make the technical effort yourself -- not just sketch things that look plausible, but build the prototype (including correct and complete binding to WinRT features and high-quality VS product tooling integration) and demonstrate a proof of concept.

    Oh, no. Please don't give me this "you just don't understand how difficult this really is, I have been doing this for years so I know much more about this than you do". C++/CX and WinRT aren't rocket science. Sorry, they just aren't. People have been mapping concepts between C++ and other technologies for years, it's a fair work, like I said, but nothing terribly difficult or grandiose like you pretend it is. Take a look at C# folks. They just took WinRT and mapped it into their language seamlessly with little fuss. Nobody has problems with what they did. Nobody. Why? Because WinRT is a better fit for .NET than C++? That's highly debatable. If you were among the C# guys you'd jump at that notion, you'd argue to death that WinRT is enormously closer to C++, since C++ is native and WinRT is native as well. No, the real reason the C# folks just took WinRT and mapped it seamlessly with little fuss is because they approached that as normal developers should, with little noise and no idiotic grand stands.

    Herb, if you want to say that this all is really terribly difficult, please show it. Right now, you haven't shown anything particularly difficult. The total of your entire reply is this - how to specify whether a C++ class should map into a interface or a class or both in the WinRT sense, and how to specify the default interface for a class. That's it, everything else was just repetitions and irrelevancies. The question you bring up is not at all difficult. That said, it is very clear that you aren't really interested in discussing it. Your position is that since I don't have a complete technical specification for what is being proposed, this can't be done. This is pathetic.

  • @Charles:

    I get the sense that many of you just don't want ANY answers that aren't "Yes, you're right, we should have implemented support for WinRT's object model and runtime enviroment in an ISO C++ solution and never seriously considered the benefits of a small, platform-specific (WinRT) language extension for simplying the expression of developer intent when programming shared, ref-counted COM objects in a new hetrogeneous programming model for Metro style application development on Windows 8".

    No, Charles. We want either "Yes, you are right" or "No, you are wrong, here is why". What we get from Herb is "No, you are wrong, but I won't show you why, this is all terribly difficult, you just don't understand, you don't have a complete technical spec so I will just point out to various things which you haven't yet mentioned in your posts and this will supposedly show that you, well, don't have a complete technical spec and thus I win". This is pathetic.

    C++/CX is real, not imaginary or speculative like the reverse of #import with wrapper classes solution.

    Right, this is your entire argument. Since we seem to be at our final words, here is the final word from me:

    What you did with C++/CX puts C++ developers into a position where they can not easily talk to WinRT from their native language. They have to use another language. Due to its viral nature and bad language integration, C++/CX is actually a worse choice for a C++ developer who wants to talk to WinRT than .NET languages or Javascript. The latter languages at least allow you to see the borders clearly.

    Me and my team are going to stay away from C++/CX. This means staying away from WinRT for some time, too.

    Have fun.

  • Herb pointed out some issues with trying to automatically expose a WinRT wrapper on top of a C++ class.  I want to pile on that with some other observations.  Some of you have been asking what is wrong with the wrapper approach and here is one issue that would need to be addressed.

    Let's say I have an interface IBaz defined in metadata.  It has one method called Baz1.  At the ABI level, it looks like this.

    struct _IBaz : public IInspectable
    {
        virtual HRESULT __stdcall _Baz1() = 0;
    };

    There are a couple of ways the high-level projection could look.  One has the high-level interface inherit from the low-level.  Note that we still need QI, AddRef, and Release in order to implement ref-counting.  This is very similar to what #import does today.

    struct IBaz : public _IBaz
    {
        void Baz1() {CheckAndThrow(_Baz1());}
    };

    Another way is to create a struct that holds onto the underlying interface rather than inheriting from it.  (This has some advantages when you try to implement the "requires" relationship.)

    struct IBaz
    {
        HRESULT QueryInterface() {...}
        long AddRef() {...}
        long Release() {...}
      void Baz1() {CheckAndThrow(p->_Baz1());}
    private:
        _IBaz* p;
    };

    There is a fundamental problem, however, as we have stated that we want to be able to define interfaces locally in "ISO C++" like this.

    struct IBaz
    {
        virtual void Baz1() = 0;
    };

    On one hand, we talk about projecting metadata interfaces into ISO C++ and then we talk about authoring interfaces in ISO C++, but the ISO C++ would be different in each case.  Note that we really need to have AddRef/Release defined on IBaz somehow.  We might be tempted to say that IBaz should inherit from IInspectable like this.

    struct IBaz : public IInspectable
    {
        virtual void Baz1() = 0;
    };

    Now, however, you have a "high-level" ISO C++ interface inheriting from a low-level IInspectable.  That doesn't make sense and it is still different from what #import would do.

    Things will only get more complicated when trying to represent a "requires" relationship or an actual class.

  • DennisDennis

    Same for me, PFYB.

    Thanks a lot for many insightful posts.

    @JimSpringfield: I would think one way to map WinRT interfaces to C++ interfaces in the world of regular C++ constructs and wrapper C++ constructs would be: regular C++ constructs use regular C++ inheritance, no IInspectable, no IUnknown; wrapper C++ constructs use COM / WinRT "inheritance", derive from IInspectable, do QI. Out of interest, I sketched how this could look and while it is perhaps too long for a thread post, it was fairly straightforward.

  • MortMort

    Charles

    > You are oversimplifying the problem. You make it sound
    > like crafting an ISO C++ solution to this WinRT-specified
    > set of constraints is simply just an option, one that is
    > no more complicated to implement effectively/efficiently/
    > effortlessly - adhering to the underlying platform's
    > object model and runtime environment rules - than a small
    > language extension. Did you read what Herb wrote? What Jim
    > wrote?

    Exactly, I think crafting an ISO C++ solution is a viable option. I did read what everyone wrote, I base my opinion in part on what was said.

    By the way, you say this:

    > I get the sense that many of you just don't want ANY answers
    > that aren't "Yes, you're right, we should have implemented
    > support for WinRT's object model and runtime enviroment in
    > an ISO C++ solution and never seriously considered the
    > benefits of a small, platform-specific (WinRT) language
    > extension for simplying the expression of developer intent
    > when programming shared, ref-counted COM objects in a new
    > hetrogeneous programming model for Metro style application
    > development on Windows 8".
    >
    > You're not going to get that answer.

    Do you mean to say that even if PFYB is right, you aren't going to say so? I hope you do realize how this sounds.

    Please think what "sense" others on this thread are getting when reading replies from Microsoft folks.

  • C64C64

    , PFYB wrote

    @C64:


    I think we can trust people in VC++ Team if they say they tried first without extending the C++ language, but it was not a good experience for the "end user" programmer, and they figured out C++/CX was a more productive tool for us.

    Why does this have to be about faith? If there are technical arguments as to why not do wrappers, why not present them? Please forgive me for being blunt, but it very much looks like the team made a mistake in not going far enough with C++ and Herb is trying to justify that mistake by any means possible. So many posts from Herb with nothing resembling a counterpoint besides "it's so difficult, you don't even understand", this has to mean something.

    My understanding was that the VC++ team tried several paths, including something similar to what you suggested, but figured out that the simpler approach for us "end-user" programmers was a language extension as C++/CX.

    I don't know if you did some COM programming, I did with C++ and ATL, and while I think that ATL is the best tool for COM programming in C++, note that you have to write non-trivial code to create a "COM" class, instead the authoring process seems to me simplified a lot with C++/CX.

    Just an example of some C++ ATL code snippet:

    class ATL_NO_VTABLE CMySimpleObject :  public CComObjectRootEx<CComSingleThreadModel>,  public CComCoClass<CMySimpleObject, &CLSID_MySimpleObject>,  public IMySimpleObject,  public ISomeOtherInterface  ...{  BEGIN_COM_MAP(CMySimpleObject)    COM_INTERFACE_ENTRY(IMySimpleObject)    COM_INTERFACE_ENTRY(ISomeOtherInterface)  END_COM_MAP()...

    There are base classes, macros... I've not seen WRL, but probably it is similar to the above approach (maybe with some C++11 features that aren't present in ATL).

    C++/CX seems to me to hide all this complexity, moving it behind the scene. This is why I kind of like C++/CX (but I've not experimented with it deeply, and in some posts you correctly pointed out some impedance mismatch with the rest of C++).

    However, I think your request of showing concrete examples of difficulties encountered by the team in following an approach similar to what you suggested is fair. These kinds of examples may be collected and presented in a future video on C9 (something like "C9::GoingNative: C++/CX Backstage - A Design Rationale").

     

     

  • CharlesCharles Welcome Change

    @PFYB:

    , PFYB wrote

    @Charles:

    What you did with C++/CX puts C++ developers into a position where they can not easily talk to WinRT from their native language. They have to use another language. Due to its viral nature and bad language integration, C++/CX is actually a worse choice for a C++ developer who wants to talk to WinRT than .NET languages or Javascript. The latter languages at least allow you to see the borders clearly.

    As I said, this is a fair statement. C++/CX is not C++. Nobody is debating this. Now, in terms of .NET languages and JS, to be fair they see what their virtual machines show them. The CLR and Chakra do all the work here (interop with the WinRT object model, GC, etc...). C++ doesn't have such a facility (VM) so the work has to be done either at the library or language level. You know this, of course. I'm just stating, again, why the .NET and JS solution to this problem is not the same and can't really be used to argue against what was done for C++.
     
    Your position is that going the language extension route changes the game and not for the better. You want technical reasons why the C++ wrapper solution wasn't deemed a viable approach. Right? Isn't this the crux of the issue?

    C

  • CharlesCharles Welcome Change

    Charles

    By the way, you say this:

    > I get the sense that many of you just don't want ANY answers
    > that aren't "Yes, you're right, we should have implemented
    > support for WinRT's object model and runtime enviroment in
    > an ISO C++ solution and never seriously considered the
    > benefits of a small, platform-specific (WinRT) language
    > extension for simplying the expression of developer intent
    > when programming shared, ref-counted COM objects in a new
    > hetrogeneous programming model for Metro style application
    > development on Windows 8".
    >
    > You're not going to get that answer.

    Do you mean to say that even if PFYB is right, you aren't going to say so? I hope you do realize how this sounds.

    Please think what "sense" others on this thread are getting when reading replies from Microsoft folks.



    No. I'm saying we have C++/CX and this isn't going to change. We also have WRL, which is a C++ library for writing exception-free COM that targets WinRT. We learned about WRL in the last episode of GoingNative. The point was made that you can (and Windows already does) write WinRT objects in WRL (so, not C++/CX). Right?

    Herb and Jim are the right folks to comment on behalf of Microsoft. Perhaps I am just getting in the way. I will therefore step back and not add any more confusion to this thread.

    Keep it going.
    C

  • @Dennis

    OK, let's go down that path.  Let's say you have the following.  (IBaz could have come from metadata.)

    struct IBaz
    {
        virtual void Baz1() = 0;
    };

    struct Foo : public IBaz
    {
        void Baz1();
    };

    For a class defined internally, this is just ISO C++.  Note that there is no ref-counting machinery anywhere.  I do "new Foo" and I can delete it.  Note that if I want to be able to delete it from IBaz, I need a virtual dtor on IBaz.  However, it is possible to get an IBaz from some other API.  If it is coming from WinRT, I will need to create an object instance that implements IBaz as the "IBaz" I get from the API will be the ABI level IBaz.  I need something like this. (Yes, this would be tool generated.)

    struct IBazImporter : public IBaz
    {
        void Baz() {CheckHR(p->Baz1());}
        _IBaz* p;
        ~IBazImporter() {p->Release();}
    };

    Similarly, when I pass one of my IBaz interfaces to a WinRT interface I will need to create a wrapper the other way. (This could be tool generated.)

    struct IBazExporter : public _IBaz
    {
        HRESULT Baz1() {...}
        IBaz* p;
        unsignedlong refcnt;
        // IInspectable...
    };

    This is exactly what .Net does for COM in creating RCWs/CCWs.  However, there is a more serious problem here because C++ doesn't do garbage collection.  In the original ISO C++ code, we manage objects by using new and delete.  (Yes, you can use shared_ptr, but that is just a layer over new and delete.)  I should either provide a virtual dtor on IBaz or I make its dtor protected to avoid calling delete on it.  However, this is fundamentally different from what has to happen with interfaces that come from outside.  If I get an interface from outside and I wrap it up in another C++ object, I have to tell that wrapper object to go away.  The only way to do that is to call delete on it.  However, that will just release the reference count.  On the locally defined ISO C++ class, calling delete will actually delete the underlying object regardless of whether someone else is holding an interface.

    There is a fundamental impedance mismatch between the C++ object model and COM/WinRT/.Net.  C# is able to support COM and .Net with minimal syntax changes because their object model already supports garbage collection and reference counting is a form of GC.  The C++ object model does not implicitly support GC which causes the problems.  C++/CLI provided a way to access .Net objects that are garbage collected,  C++/CX is almost identical to C++/CLI and provides the same services for WinRT.  This is not a coincidence that the same syntax can work for both.

    In all honesty, I would have felt pretty bad if we did ignore what we did in C++/CLI and did something completely different.

  • GlenGlen

    @Jim

    I totally appreciate your comments. I don't doubt that C++/CX is a valiant compromise to fix and solve a lot of Microsoft legacy and desires.

    However, after listening to all of the debate and some great ideas, I have to, again, forward my conclusion that C++/CX just can't be recommended.

    It's not to blame you or herb, I think you've all clearly done some great work, some of the best work in many ways. You, especially, have done a great job of explaining yourself. Maybe the problem is the constraints you started with?

    Regardless, I honeslty can't recommend C++/CX to anyone. If it's any consolation, I can't recommend C++/CLI either. I warmed to that before in desperation, but I got it sorely wrong.

    C++/CLI is patch to an insufficiently performant problem that is .NET.
    C++/CX is a homage to COM that still requires too much work.

    Both make C++ the wrapper guy *for my own code* and require too much discipline to keep an ISO C++ code base sane and viable. Due to that, I sincerely believe C++/CX/COM/WinRT and C++/CLI do more harm to C++ than to promote them and that WRL serves no value in this either.

    This is no C++ renaissance, far from it, just a native one. I have maintained that this was looking that way for some time. I am sad to have seen that demonstrated. I have enjoyed the discussion though and the public contributions.

    But C# will just go from strength to strength in comparison to C++ on MS platforms and C++ is a laughing stock in comparison with its two notions of class, (one small one big as Charles would say) and the small work required to synch them, that is a burden unwanted. None of this is C++ itself's design failings IMHO.

    I know you all have really great (for MS) reasons for why this was all done this way and constraints set for you that made this design inevitable. I've really tried hard to stay out of the "no language extensions" technical debates to give everyone as much scope to find any solution that I felt was workable that I could also see WG21 drawing together compatibly, but I just can't see that future.

    MS now needs some heavy weight help from Bjarne or Dave A etc. to show that that future is possible. It's crazy that I have to say that because I know Bjarne and Herb communicate so I feel that he must in some way tacitly approve (to some definition) of your work, but I just can't see the light regardless.

    As yoda says, the future, uncertain, it is, dark. Search your feelings.

    So I searched my feelings. It comes down to this:

    1. This design does more for MS than it does for me or my customers. Rewrite/refactor, for what?

    2. I am not the wrapper guy. I will not manually wrap my own c++ in "c++" like this. I don't want signficant work to keep even the simplist ISO function not Microsoft specific or easily useable from other languages or modules or callers like IE.

    3. I don't want any solution here that just damages ISO C++. I believe COM 1 did, .NET did, and C++/CX still does that. Where are they now? C++/CX makes .NET redundant and its sibling, but it is no better for me, just maybe MS.

    4. If the COM model is what makes this so hard, maybe COM is the problem. Cut it down or out. If COM or something similar is what C++ is lacking, WG21 will surely roll it out. I have troubling seeing it will be C++/CX or a COM that isn't anything but drastically altered.

    5. I have to believe ISO can draw what you come up with together that does not great a frankenstein. I'm not seeing it. If something like COM is needed, that's the door I will be watching now.

    I am sure you've read my elaboration on that I feel C++/CX means to the average developer (me at least in both parts). I posted before "C++ good for libraries". Do comment, it's non technical.

    That's what I feel. I will not recommend C++/CX to anyone as it stands.

    In conclusion, for once, I agree with Charles.

    Hey said:

    "I get the sense that many of you just don't want ANY answers that aren't "Yes, you're right, we should have implemented support for WinRT's object model and runtime enviroment in an ISO C++ solution and never seriously considered the benefits of a small, platform-specific (WinRT) language extension for simplying the expression of developer intent when programming shared, ref-counted COM objects in a new hetrogeneous programming model for Metro style application development on Windows 8".

    You're not going to get that answer."

    He is absolutely correct in essence on both accounts.

  • DennisDennis

    @Charles

    > Your position is that going the language extension
    > route changes the game and not for the better. You
    > want technical reasons why the C++ wrapper solution
    > wasn't deemed a viable approach. Right? Isn't this
    > the crux of the issue?

    Yes, Charles, PFYB, Tomas, KMNY_a_ha, myself and I think several others here wanted technical reasons why the C++ wrapper solution wasn't deemed a viable approach. I have to work hard to suppress my sarcasm at answering this after numerous posts above which ask this very clearly.

  • DennisDennis

    @JimSpringfield

    To recap: IBaz is a C++ interface (deleted via delete and virtual dtor), _IBaz is its analog for WinRT (deleted via Release), IBazImporter is a way to wrap _IBaz into IBaz (deleted via delete and virtual dtor), IBazExporter is a way to wrap IBaz into _IBaz (deleted via Release).

    > I should either provide a virtual dtor on IBaz or
    > I make its dtor protected to avoid calling delete
    > on it. However, this is fundamentally different
    > from what has to happen with interfaces that come
    > from outside. If I get an interface from outside
    > and I wrap it up in another C++ object, I have to
    > tell that wrapper object to go away. The only way
    > to do that is to call delete on it. However, that
    > will just release the reference count.

    Why is this a problem? You do a call into WinRT via some other interface (ISomethingElse). The call creates a WinRT object that implements _IBaz. The wrapper code wraps _IBaz into IBazImporter. You get a pointer to IBazImporter. IBazImporter implements IBaz, you call some functions on IBaz. Some time after you decide you no longer need the object. You call delete on IBazImporter (automatic with smart pointers). IBazImporter calls Release on the WinRT object. This decrements the reference count on that object. If the object has no more references it is destroyed. If the object has more references, this means someone (likely you) handed a reference to that object to someone else and that someone else is holding onto that reference. This can be a different instance of IBazImporter or a different object depending on the implementation of the object and the implementation of wrapper code. If someone else is holding onto the object, it doesn't get deleted when you destroy your instance of IBazImporter and this is good, this is what you want.

    > On the locally defined ISO C++ class, calling delete
    > will actually delete the underlying object regardless
    > of whether someone else is holding an interface.

    Yes, exactly. This is OK.

    If you get an instance of IBaz by doing new on a C++ class that implements it, you delete that instance by doing delete. Are you thinking about the case when you have to pass that instance of IBaz to WinRT and you don't want to hold onto it anymore in your code? In this case we have to replace the ownership rules from ctor / dtor to AddRef / Release. This can be done by creating an instance of IBazExporter and passing it the existing interface to IBaz transferring ownership using an appropriate ctor.

  • CharlesCharles Welcome Change

    @Charles

    > Your position is that going the language extension
    > route changes the game and not for the better. You
    > want technical reasons why the C++ wrapper solution
    > wasn't deemed a viable approach. Right? Isn't this
    > the crux of the issue?

    Yes, Charles, PFYB, Tomas, KMNY_a_ha, myself and I think several others here wanted technical reasons why the C++ wrapper solution wasn't deemed a viable approach. I have to work hard to suppress my sarcasm at answering this after numerous posts above which ask this very clearly.



    It's not an approach that's going to be implemented. This answers the bigger question: Is there going to be an ISO C++ solution to this problem instead of a language extension? The answer can't be stated any clearer than it already has been.

    I'll leave it to Jim to reply to your reply to his reply. That said, let's please be respectful of his time. Also, I'd really like to interview him about ATL not just C++/CX.

    C

  • @Dennis

    The problem is that if I am holding an IBaz, I don't necessarily know where it came from.  If it came from WinRT I should call delete when I'm done with the interface.  If it came from a local class, that will destroy the object and I probably don't want to do that.  Although these two interfaces are the same, delete does something fundamentally different.  The ownership rules are just different.

  • DennisDennis

    @JimSpringfield

    When IBaz comes from a local class, calling delete on it deletes an instance of that local class. When IBaz comes from a wrapper class for WinRT's _IBaz, calling delete on it deletes an instance of that wrapper class, which calls Release on _IBaz. The ownership rules are different, yet in C++ you always call delete and this either deletes the object or merely asks it to delete itself via Release.

  • DennisDennis

    > If it came from a local class, that will destroy the
    > object and I probably don't want to do that.

    Do you mean the case where you don't want to destroy the object because you handed a reference to it to some other code and thus you want the object which you originally created with 'new' to live by the COM rules now? I commented on that in my earlier post -- In this case we have to replace the ownership rules from ctor / dtor to AddRef / Release. This can be done by creating an instance of IBazExporter and passing it the existing interface to IBaz transferring ownership using an appropriate ctor (or make-function).

  • C64C64

    , Charles wrote

    [...] Also, I'd really like to interview him [Jim] about ATL not just C++/CX.

    That's a great idea: the ATL inventor speaking of its own programming creature!

    If possible, I'd like to listen also to historical perspectives on ATL, e.g. what were the problems at the time (maybe COM programming in pure C++ was too hard, MFC way of doing COM was too bloated, and so a better ad hoc library was needed? I also think ATL was very advanced for that time, because the library is heavily template-based, and uses several advanced techniques like mix-in classes and so called "compile-time virtual functions calls"); what design decisions were on the table, why they chose the option X instead of option Y, etc.

    I'd like also to listen to something on WTL, which is built on top of ATL and offers nice object-oriented C++ wrappers around raw Win32 handles and C API functions.

    I believe ATL is at the core of lots of Windows native software: e.g. shell extensions, IE add-ins, etc. maybe also software written by Microsoft itself, and snappy apps like Google Chrome use ATL and WTL too.

    Thanks!

  • CharlesCharles Welcome Change

    @C64: Thanks. I'll be sure to ask!

    C

  • DennisDennis

    OK, Jim, I hope we can count this particular matter resolved by now.

    Charles, take note.

    My final word is that I believe I and others were not here to lay blame and to force the Visual C++ team to say that doing C++/CX was a mistake. What we wanted was a technical discussion on why an ISO C++ solution was not deemed viable. I was (still am) completely willing to be pointed to something that makes such a solution unviable. I thought though that if during the discussion it turns out that an ISO C++ solution is viable, maybe the team would be willing to do it for whatever version of VS, in some form. We never had the discussion we wanted. The summoned C++ heavyweight Herb Sutter spent the majority of his time talking about things that were irrelevant to the topic of an ISO C++ solution as discussed in the thread, to everyone's frustration. This is a shame.

    In the end, it seems to me that an ISO C++ solution is completely viable, but we aren't going to get it from Microsoft due to stupid political reasons we don't completely understand. We will also have a hard time creating such a solution ourselves since that requires interacting with the compiler. This is a TOTAL shame.

    The trust between me as a C++ developer and Microsoft as a maker of my tools has never been thinner.

  • hmmhmm

    I'm pretty sure people would complain less here if the C++ team had focused more on C++11. Not many people even care about C++/CX now, let's take a look at VC++ uservoice - there's the proof. We were expecting a modern GUI library to replace MFC, but what we get is something that can only be used for metro apps and has a horrible syntax.

    Let's leave out the fact that the C++ team spent their time on C++/CX instead of C++11. What is there to stop them from implementing the C++11 standard now? GCC and clang C++11 statuses get updated every few weeks, and every time there's huge progress. Perhaps Microsoft should directly tell us to move to C# if that's their intention.

  • GlenGlen

    Dennis says:

    "The trust between me as a C++ developer and Microsoft as a maker of my tools has never been thinner."

    Here here.

    It's clear to me that C++/CX is going to die a death like COM, mananged extensions, and C++/CLI before it. The only question is how much it again divides C++ users before it happens and if that means it will take down C++ with it? My money is on C++.

    The ref class adds zero new invention to C++ - or language design in general. The ref class's only purpose is to serve as a vendor specific, lock in replacement, for something the language already has - for no greater purpose than to allow Microsoft to get under every class the C++ developer ever writes - at the developers own expense! - until the end of time - so that Microsoft can invoke those classes in a vendor specific way to support their own platforms like IE.

    Are you nuts? Who will vote for that?

    Your platforms are losing ground. IE loses ground to Chrome every week and has been since Chrome was released - just as Microsofts phone platform has also been perenially losing ground to Android and iOS.

    The problem is obvious: C++/CX's lack of invention materially damages C++ by expecting C++ developers to enlist to manually wrap *everything* they write *for ever*, purely to help Microsofts platforms. This asks the C++ developer to simultaneously *harm C++ and their own productivity and viability in the process*.

    Why Microsoft thinks C++ developers would support such a dreary plan this time, when they didn't before when it was under the guise of COM and C++/CLI that failed last time, is a thing to wonder?

    C++ developers have never enjoyed such propositions inflicted on them but when Microsofts own platforms are under attack by better competitors like Chrome or more flexible ones like LLVM, for Microsoft to suggest this path again starts to border on insanity.

    Microsoft, fighting your customers is the sign that is sent to you to recognise when you are doing something wrong. You may one day get back to helping your customers instead of helping yourself but by that time, if all your credibility is gone, what will it matter?

    You are losing friends you can't afford to lose. I've told you why.

    Listen to Dennis:

    "The trust between me as a C++ developer and Microsoft as a maker of my tools has never been thinner."

  • Will there will be an compiler that produces ARM code that supports these extensions?

     

  • CharlesCharles Welcome Change

    Dennis says:

    "The trust between me as a C++ developer and Microsoft as a maker of my tools has never been thinner."

    Here here.

    It's clear to me that C++/CX is going to die a death like COM...

    It's clear to me that you haven't been following along closely here. The point is that COM (well, WinRT, which is based on COM, which presents a programming surface that is much like COM, but it's WinRT. It's also COM...). Did you not watch the BUILD WinRT presentations I linked to ealier in this thread? Watch.

    In terms of C++11, you already know that the VC team will release new C++11 language features post VC11, pre VC12. Herb stated that at BUILD. There's a lot of great information in the BUILD conference's keynotes and sessions that explain a lot of the Why. Seems this level of understanding is missing here (why are we doing this? what's going on here?). At least, this is what I can gather from an assertion that WinRT will die just like COM did...You do see the irony in such a conviction, right?

    C

  • WarrenWarren

    Charles, COM is not dead as a technology underlying WinRT but it is definitely dead as a technology that developers program for. Some developers still write COM code, but the vast majority only use COM if they have no other choice. In the past 5 years I have not seen any project that would use COM for what it was intended to be used - to separate code into components and connect these components together. I saw .dll's connected with plain C interfaces, .dll's connected with plain C++ interfaces (yes, this is vendor-specific), components talking to each other via .NET, extensions done via Python, extensions done via Lua. I never saw COM used for anything besides satisfying needs imposed by the system. As a technology that developers, not automatic tools, use, by choice, COM _is_ most definitely dead.

    There is also a bigger message. I agree with Dennis one hundred percent. I am going to echo his words:

    The trust between me as a C++ developer and Microsoft as a maker of my tools has never been thinner.

  • I just wonder if this "syntax" would/could 've been used in order to stay with ISO C++

    class X

    {

    REFCLASS;//this is a macro, other tool may be needed but other than that nothing changes

    };

    continue from the comment above:

    if class needs to be WinRT aware it has to have as its first line REFCLASS macro. That's it. Compiler or another tool is aware of that and based on that generates necessary info/metadata. Syntax and everything stays exactly the same as ISO C++.

  • WarrenWarren

    KMNY_a_ha: I would go for a different syntax (I like the approach with pragmas suggested by Dennis), but, yes, this is the idea.

  • C64C64

    , Warren wrote:

    Charles, COM is not dead as a technology underlying WinRT but it is definitely dead as a technology that developers program for.

    Are you sure?

    DirectX (and, in particular, Direct3D/DirectGraphics) is a COM API, and is widely used to program best-selling videogames.

    If you want to build Shell extensions for Windows, you have to use COM.

    If you want to write add-ins for IE, you have to use COM: "[...] You can create add-ins using .NET and Script, but both have significant limitations as well as performance concerns. If you want to write an add-in of any complexity, you'll almost certainly want to write it in C++."

    The new Windows Ribbon API uses COM as well.

    etc. ...

     

  • WarrenWarren

    C64

    Yes, that's what I meant by "needs imposed by the system". Since Microsoft keeps using COM in their APIs, developers using Microsoft technologies sometimes have to use COM to some level as well. Frequently, all this means for a particular project is that someone writes a huge wrapper around the entire subsystem that uses COM - or reuses an existing wrapper written by someone else - and the rest of the team use that wrapper. The original purpose of COM was something else - to allow separating your code into components and let these components talk to each other using a strict ABI. As I said, in the last 5 years I have never seen anyone do that for their own code, all uses of COM that I saw was when someone's code had to talk to a Microsoft API that uses COM. To me that says that COM is dead for everyone but Microsoft.

  • GlenGlen

    @C64, as Warren says, including MS in your user base is dubious. One supporter of a product, who is also the inventor of it and most skilled user of it, does not make a happy eco system IMHO.

    Even on Windows, MS authors COM classes, but barely anybody does unless it is trival for them to do so, which for C++ developers it isn't without a significant negative impact to their ISO code base.

    Its barely used on any other platforms where it isn't Microsoft related?

    For a technology that's existed for so long, that's pretty poor take up don't you think?

    If MS folded, do you think COM would go onto to have a happy future? I doubt this will fly even without MS folding. I doubt there are any companies that use COM that aren't using it because of Microsoft. There must be a reason for that.

    Please, can someone also inform me where the irony is that Charles is talking about:

    If there is a level of understanding missing as Charles puts it, it would appear to be from everybody, because from the comments here, despite some 220+ posts, I'm not aware of a single person who has changed their mind to support C++/CX at all if they were not supporting it to begin with. Zero turn arounds seems a pretty poor success rate for such an effort and the customers willingness to partake.

    Compare that to the 100% enthusiasm that more C++11 support has, that was garnered with zero effort required from Microsoft at all, but that despite that, it missed this schedules delivery bus. Now that is ironic.

    What's to misunderstand about that?

    How about a bet. I'll take a gamble that says, @PFYB, @jalf, @KMNY, @Warren, @Dennis, @Garfield etc. to name just a few, aren't suddenly now giant C++/CX, winrt and COM supporters now, and rushing out converting all, infact any, of their code over to ref classes? Do let me know. I'm keen to know if I was left the only one unsold or with misunderstanding.

    It's great that VC Next might oneday (no dates) have better C++11 support, but I wont be buying it. This thread has demonstrated to me that any C++ renaissance is not safe in MS hands. The time to get out is now. Hitching a ride on the next big thing that isn't doesn't make sense.

  • @Glen, I certainly am not going to even touch WinRT. As've been proven here on this thread CX is a total unnecessary, foreing to C++ without legitimate right to exist.

    But Glen, this will not bother MS. We are not their target customers - .NET crowd is. They will jump on CX. We (C++ guys) were just an extra - They (MS) speculated along this lines: "if it happens (that C++ guys will want to use it) that's fine, if not we (MS) can live without them quite happily."

    They didn't care about us in the past and they will not in neither present nor future.

    Why do you think this syntax is so .NET-ish? To accomodate C++ folks? Buhaha! That's so obvious - .NET crowd is what matters for MS not we.

    C++ rules and rocks!

    Forever!

  • dbudbu

    Who cares about VC11? VC11 is completely broken by design!

    see: https://connect.microsoft.com/VisualStudio/feedback/details/690617

    Until this BUG is fixed VC11 will be useless for most real world developers!

  • @dbu: Unfortunately must disagree with you. People will buy it, people will use it. Just because you, I and some other few people didn't get the "WinRT thing" it doesn't mean anything and MS knows about it. They will push with stubbornity of a donkey every new technology however badly designed. It doesn't matter - they can afford it.

  • hmmhmm

    VC11 not supporting XP really seems like an attempt to kill C++ in Microsoft's world. .NET 4.5 will surely run on XP right? I've actually heard rumours that Microsoft pays universities to teach C# and NOT teach C++.

  • CharlesCharles Welcome Change

    VC11 not supporting XP really seems like an attempt to kill C++ in Microsoft's world. .NET 4.5 will surely run on XP right? I've actually heard rumours that Microsoft pays universities to teach C# and NOT teach C++.

    Whatever... So wrong on so many levels...
    C

  • CharlesCharles Welcome Change

    ...

    The original purpose of COM was something else - to allow separating your code into components and let these components talk to each other using a strict ABI.

    Yes. This is precisely what WinRT does - via a COM-based internal implementation - and WinRT components can be written in very different languages... Your arguing against COM, not C++/CX. If you don't want to use C++/CX to author WinRT components then - again...- don't use it. Use ISO C++ and WRL. Or, write your own wrapper. If it's so readily possible to implement a library-only solution, then do it. Nothing is stopping you as you have the low level abstractions (via, you guessed it, WRL) at your disposal. COM is the glue. If you don't want to write COM code, then that's the issue, not C++/CX. The whole purpose of C++/CX is to abstract away COM complexity. As Herb says, any way you choose to do this will require some form of extension (COM is a foreign object model to C++). C++/CX has been deemed the most user-friendly approach to solving this problem. Feel free to prove us wrong.

    C

  • , Charles wrote

    *C++/CX has been deemed the most user-friendly approach to solving this problem. Feel free to prove us wrong.

    C

    @Charles didn't we prove you  wrong (to MS, mr sutter and you personally) by giving a number of differently approached counter examples written in pure ISO that would achieve exactly the same goal as C++/CX and actually would conform to ISO C++?

    Are we having/had the same discussion here?

    And as for mr sutter and his attitude:

     "hey, this thread has half the word count of exceptional c++! I'm not gonna read it!" - pathetic

    You also are saying:

    COM is a foreign object model to C++).

    Yes, but in order to consume it you use C++ syntax and you have C++ semantics. This is NOT true for C++/Cx - and that's the whole point, I and others were trying to make but apparently this genius mr sutter couldn't neither grasp it nor explain why staying within ISO C++ would be not possible and he and his team had to come up with CX. WOW!

    The only person here from MS who has to be given fair play star is Jim Springfield. I and others may disagree with him but at least he didn't try to pull wool over our eyes, on the contrary to mr sutter and Jim at least read this tread and listened to what we want/have to say.

    As for over all mr sutter's appearance here - WOW!

  • TomasTomas

    Charles wrote:
    > *C++/CX has been deemed the most user-friendly approach
    > to solving this problem. Feel free to prove us wrong.

    I am working on the code generating approach discussed above. In this phase I chose a small subset of WinRT and I write all the code by hand but I am clearly separating user code from the generated code. User code is ISO C++ without hats, ref news and Platform::Strings so it's much more easier to use than C++/CX. Generated code uses WRL. I was already successful with deriving Application class and loading some XAML into it. When I have UserControls and events working I post the link here. Then we will have something concrete to discuss and we can prove the redundancy of CX.

  • CharlesCharles Welcome Change

    @Tomas: Great. Code speaks louder than words. This has been a thread of mostly hand waving...

    Good luck, Tomas!

    C

  • hmmhmm

    Charles, let's see what VC11 delivers for C++ developers.

    1. No new C++11 features. (yeah in future, before VC12, when???)
    2. Programs compiled with VC11 won't run on XP SP3 (statistics show that XP is still the most used OS out there).
    3. No modern desktop GUI libraries, except the one for metro (no one cares about metro).
    4. WinRT and C++/CX that is of no use to real C++ developers.

    I don't think many C++ developers will be buying VS11. The only thing VS11, compared to VS10, gives you is the lack of XP support and 2-3 additional C++11 features. Surely Microsoft must know that such steps will not be welcomed by C++ developers. But they're not afraid of that, since their goal is to kill C++.

  • GlenGlen

    @Charles

    "Great. Code speaks louder than words. This has been a thread of mostly hand waving"

    Thanks. I suggest you quit.

    You forget that it's Microsofts job to do this, not ours. We don't get paid for it. One might call it arm waiving, saying hey, don't do this, but if it suits you to characterise that as Customers being lame "hand waivers" for their efforts, go for it, but its an unusual stance, particularly for someone working in developer engagement as yourself.

    Since that's your core belief, let's talk about hand waiving. What have Microsofts hands been doing for C++ users since VC6?

    1. Diluting C++ with Managed C++ extensions which were an epic failure.
    2. Diluting C++ again with C++/CLI, a whole new language to target a managed runtime that was less peformant than what it replaced.
    3. Diluting C++ again with C++/CX which is largely the same in syntax and tact but repurposed to flip flop back to native all over again.
    4. Routinely closing out bugs in a condescending way, to developer consternation, rather than fixing them.
    5. Flunking the phone market with no C++ support still, despite getting whipped senseless by Google Android and Apple IOS.
    6. Failing to implement as much of C++11 as those rivals that are doing the whipping like apple/clang, gcc, and ibm; apparently because "Microsoft didn't know customers wanted it".
    7. Bystanding as the stock price of those same competitors rises beyond Microsofts, evidently without a clue why.
    8. Contributing pitifully back to the C++ eco system considering Microsofts size, budget and abilities despite Microsofts own reliance on C++.
    9. Losing market share and adopting restrictive practices. VS11 drops XP support as IE9 did. Chrome retained XP support and now gains on IE9 on a daily basis on past and future platforms. Watch VS decline too. Go figure.
    10. It engages Customers too late in the design cycle, fragments their market and insults and thwarts their customers needs.

    In this time of Microsoft failing to execute, everybody else has.

    Microsoft seems content to just insult their Customers. Labeling them as hand waivers just rubbishes their aspirations.

    In contrast look at Boost:
    1. It has contributed many full libraries to standard C++ with more to come.
    2. It has fostered great conventions that are as much about C++ as Boost.
    3. It has even diluted its very successful Boostcon brand FOR C++, renaming it C++Now for the greater good of the language and its customers. Smartly realising what's good for C++ is good for itself and everyone else.
    See: http://cppnow.org/
    4. It routinely engages in ideas to meaningfully extend C++ in both language and libraries in a thoughtful, consultative way, with great yet simple discussion threads. That aren't just all about themselves.
    See: http://cpp-next.com/
    5. It has credibility with its community far far far in excess of anything Microsoft can or will muster, while Microsoft has virtually none in comparison.

    So next time you want to talk about hand waiving, think about that. Then put your hands over your mouth.

    While you are at it, since you are "encouraging" Tomas's efforts, do we take that as a guarantee Microsoft will use it, if it works? Or was that just you hand waiving?

  • CharlesCharles Welcome Change

    http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-4-Jim-Springfield-on-ATL-GoingNative-Conference-Register-Today

    Smiley
    C

  • CharlesCharles Welcome Change

    @Glen: Well, I provided links to both folks talking about WinRT internals and folks talking about C++/CX internals (and showing you the exact code that hats and refs compile to...). No hand waving there. We care about C++ and C++ developers. You have to understand that the VC++ team has many masters. ALL of our core products are written in C++ and compiled with cl. The team that makes this toolchain must support things like Windows, Office, SQL server. How do you expect them to do everything you want when you want it? They DID provide a non-C++/CX solution to the WinRT component authoring problem. How many times do we have to say the same thing. Tomas gets it. He's actually using it in his exploration of an alternative solution. One more time: WRL.

    Please understand that your perspective is appreciated - if it wasn't Herb and Jim wouldn't have spent time here explaining themselves to you. We wouldn't have a thread with over 230 replies. I wouldn't spend time on this thread and salute you in the latest GoingNative episode. You watched it, right? We welcome your feedback. We also appreciate what Tomas is trying to do - in code, not words. We've already said it's possible, just not practical. Perhaps Tomas will learn that. Perhaps he'll prove us wrong. That said, as said many times, C++/CX exists only to make it easier for C++ developers to prorgam a single platform, a single ABI, a single product.

    Please give the VC team a break. They too, were misguided for 10 years as we - Microsoft -assumed .NET would be everything and everywhere and everyone would develop in C#. Can they have some time to catch up? Please stop casting them as incapable. In contrast, the VC team is composed of some of the most talented engineers in the industry - and they love C++ developers and especially C++. They ARE C++ developers... They compile Microsoft.

    Respect.

    Enough of this. Why don't you come to the GoingNative conference in Feb (all of you, please) and we can debate this stuff over some beers?

    Peace,

    C

  • WarrenWarren

    Charles

    I am not sure what exactly is your point on COM. I believe I expressed myself clearly enough and I am not sure if you agree or not. Perhaps it is best not to continue.

    I would like, however, to respond to this:

    > This has been a thread of mostly hand waving.

    You imply that those of us who were asking you in this thread about why you didn't support WinRT in C++ without extending the language are somehow in the wrong because we didn't provide you with the exact code that implements this vision as it applies to your compiler? Is that what you are saying? This is ridiculous.

    The thread can be summarized as this:

    Users > Hey, we don't like C++/CX, here is why. Why didn't you guys do it all in C++, here is a possible approach, are there any problems here we are missing?

    Microsoft > C++/CX is the best way. We won't point out any problems in your approach, but we assure you it is a bad one. Just trust us.

    Who is hand-waving here?



  • Please give the VC team a break. They too, were misguided for 10 years as we - Microsoft -assumed .NET would be everything and everywhere and everyone would develop in C#. Can they have some time to catch up?

    @Charles, you know I really, really would like to believe in that but first:

    1. Actions speak louder than any voice - where is C++ at MS? What are the plans for C++ at MS? Do we as devs know anything about it? The only thing we know is that you (MS) don't care about C++ and C++ community (because of the actions MS took, not because what MS says) 

    2. Would it be fair to say that now MS assumes everyone will develop in C++/CX? Because mr sutter says it's great, so surely it must be, mustn't? O my God...

    3. Would it be fair to say that if you come to someone's country you behave according to this country rules, not the one from your homeland? C++ isn't your world/country yet you treat it as if it was invented/owned by you. How arrogant is that?

    Enough is enough. Too many times MS threated C++ community like not even second class citizens. Arrogant, dismissive attitude was the way to go. Even few weeks ago, what was it? C++ renaissance? Why didn't you play straight? Why did you pretend, hiding behind names (C++). What does it says about your attitude towards C++ and C++ community? And as for Diegum expanation for lack of C++11 support in VS2012 - because we didn't know you (developers) want that. How arrogant, insulting is this? Why can't you (MS) get it that people are not sheeple?

    Charles, on a personal note, I really have nothing against you. I know that we've had little "incident" in the past but it's a past. I think that you are ok guy. I also have a weak spot for a native americans since childhood (would you believe that my wife's sister is married to a Blackfoot and they live here in Ireland few years now?). But what I'm driving at is that (if you really care about C++) you are in a very unfortunate position that you work for a company which interest you obliged to protect and those interests are nowhere near yours and ours, and you just simply cannot say what the things really look like. We on the contrary can. From the perpective of C++ community MS (with mr sutter as a main C++ architect) betrayed this language and this community - once again. As simple as that. And as long as this won't be fixed no words, no amount of beer, no plastic beads Wink will bring happines and good relationship between our community and the company you work for.

    Peace

    As a sidenote w/r to VS - I personally stopped using it at home shortly after build conference, and judging by how things are going for this once great IDE won't be using it in the near future.

  • CharlesCharles Welcome Change

    Charles

    I am not sure what exactly is your point on COM. I believe I expressed myself clearly enough and I am not sure if you agree or not. Perhaps it is best not to continue.

    Not sure what you mean. What point?


    I would like, however, to respond to this:

    > This has been a thread of mostly hand waving.

    You imply that those of us who were asking you in this thread about why you didn't support WinRT in C++ without extending the language are somehow in the wrong because we didn't provide you with the exact code that implements this vision as it applies to your compiler? Is that what you are saying? This is ridiculous.



    Well, no. Not really...

    Some people here said we did the wrong thing, that C++/CX was unecessary, that there's a better solution, an ISO C++ solution, a reverse of #import solution with wrapper classes... Herb and Jim provided answers and insights into why (and how) this extension was deemed the right solution. Please read Herb's and Jim's replies. Then, read them again.

    We will have to agree to disagree and move on, Warren...

    Tomas, good luck. Please do share your findings

    C

  • WarrenWarren

    Sorry, Charles, but it is not just that we will have to agree to disagree. What you are saying is just not true. Neither Jim nor Herb provided an answer as to why a language extension was necessary. Neither provided a significant critique of the approach with #import and the reverse of #import.

    This is not a matter of disagreement. This is a fact. You can't dispute this.

    You say we have been given answers, Charles, but I don't see them. Nobody sees them except yourself. You can't point to the exact posts and lines with the substantiated (I will repeat this for you: substantiated! "we did C++/CX because it was the best way" does not count!) answers, yet you say we have been given these answers. This IS hand waving, and the guy who does the most hand waving here is you, Charles.

    I am out of here.

  • CharlesCharles Welcome Change

    @Warren: I'll copy the last paragraph of Herb's very first reply, which echoes what I and others have been saying (though not as eloquently as Herb) as my final word on this thread because it contains the most salient points, the ones we're apparently endlessly talking around (in circles):



    This can't be said enough: C++/CX and WRL are special-purpose tools, not replacements for portable ISO C++. The guidance is the same for all the Microsoft-supported languages that are WinRT-enabled: You should continue to write nearly all your code in your normal language (in this case portable ISO C++; for .NET programmers, C#; for web programmers, Javascript) and use WinRT only on the boundary where you want the cross-language, ABI-safe, etc. environment. Just like COM or CORBA. Because WinRT is COM.



    This concludes my time on this matter and this thread (let's revisit in 6 months or so, let's see what Tomas comes up with, too).

    Thanks to all of you for the discussion and for refraining from taking this into a fire pit of conversational discord. I'm proud of all of you for keeping calm, not slinging insults (though we came close in a few places, but never crossing the line, not really).

    In the spirit of Thanksgiving, I'm thankful that we have an open environment like Channel 9 to have these sorts of conversations and that smart, passionate and opinionated developers have a safe place to argue, in peace. Smiley

    C

  • WarrenWarren

    Very good, Charles, this quote DOES NOT ANSWER the question we have been asking you all this time - why a language extension was necessary. You claimed a number of times that this question has been answered. Everyone disagreed. I challenged you to point out what the answer was. You failed to do that.

    Having an open environment like Channel 9 is great, but this environment is of limited use if all you are doing with it is delivering lectures and basically ignoring all feedback.

    Happy Thanksgiving.

  • DennisDennis

    Warren, exactly!

    Charles, for the last time:

    1. The topic of the episode was C++/CX.

    2. In the comments many people expressed their dissatisfaction with C++/CX, largely because it seems totally unnecessary. These people explained what the C++ solution would be and asked you what was wrong with that solution.

    3. You invited other people from Microsoft to take this question.

    4. The invited people did not answer this question. There was a little bit of talk around the topic, but nothing direct. We clarified and repeated our question again and again, waiting patiently for when you will finally stop talking about side topics and take the question seriously. It never got to this.

    Now you pretend like our question has been answered. Yet you fail to communicate what that answer was.

    Not good.

    Warren is right, Charles. It is good that you have this site where we can ask various questions. But being able to ask questions doesn't matter much when these questions aren't being taken seriously enough as to be actually answered.

    Happy holidays to all.

  • CharlesCharles Welcome Change

    @Dennis @Warren:

    Read this again (and again, if need be): http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-3-The-CCX-Episode-with-Marian-Luparu#c634569364042591649

    Then, read this again (and again, if need be): http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-3-The-CCX-Episode-with-Marian-Luparu#c634569808040992902

    Then, read this again (and again, if need be): http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-3-The-CCX-Episode-with-Marian-Luparu#c634570235119785552

    Then, read this again (and again, if need be): http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-3-The-CCX-Episode-with-Marian-Luparu#c634570604363805794

    I don't think anything else needs to be said on the matter. It's clear that:

    1) You are free to think what you want
    2) You can express these thoughts here, freely
    3) Your questions were answered (in my opinion) - read the replies above and let the information sink in. Don't just assume what's being said is wrong because it's not what you want to hear.
    4) C++/CX is shipping in VC11 and will be the way you wrap ISO C++ inside WinRT components - if you choose to (it certainly makes targetting a single ABI much eaiser for you).
    5) You don't have to use C++/CX to author WinRT components in C++ at all. Use WRL - as you learned in the WRL GN episode. Watch that again, for a refresher on the subject: http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-2-C-at-BUILD-Windows-Runtime-LibraryWRL-Meet-Tarek-and-Sridhar

    Cheers,
    C

  • RonRon

    I thought this thread was finished but apparently not.

    Charles, all you did was relink the same posts that do not contain any answers. It is telling that you can not say what the answer to the question posed by Warren and Dennis and other guys here is, for third (or fourth?) post in a row. Stop this. This is dumb.

    Take your own advice and reread the replies you link. Let the information "sink in" as well. These replies DO NOT ANSWER THE QUESTION.

  • WarrenWarren

    Charles

    I reread your posts and I think it can be that you just don't understand the technical side of what we are talking about here.

    This quote of yours:

    > We also appreciate what Tomas is trying to do - in code,
    > not words. We've already said it's possible, just not practical.
    > Perhaps Tomas will learn that. Perhaps he'll prove us wrong.

    The question of whether a third party can do what we would like to have in C++ instead of C++/CX has appeared in this thread more than once. The answer is that a third party can do #import by parsing metadata, but doing the reverse of #import would be very hard for everyone but Microsoft since this involves parsing C++ code. You do the parsing as part of your compiler, we don't, so doing the reverse of #import is much easier for you than it is for us.

    In terms of #import, me and some other people on my team did write a prototype of a tool that takes a WinRT module and generates C++ wrappers for that module. I guess Tomas and maybe other people too are working on something similar. It works, but it is not enough. We do need the reverse of #import, and we can't do it without taking an existing C++ compiler or code checker and putting the required code generation into that compiler. If we had our own C++ compiler, this would be easy. But we don't, so this is difficult.

    Neither me nor Tomas nor any other third party can learn that doing C++/CX in C++ is "possible, but not practical". All we can learn is that it is not practical for us, since we don't have a C++ compiler as one of our projects. You do have a C++ compiler, so this is entirely different for you. You have 90% of the work done already. In fact, since you had to alter the compiler to emit metadata for C++/CX, you have 99% of the work done already.

    Neither me nor Tomas will be able to prove you wrong by our work alone. We don't have the source code for your compiler, so even if we do alter someone else's compiler that won't prove anything as regards VC++.

    I hope this much is clear?

    To your points:

    We are free to think what we want - thanks. We can express these thoughts here - thanks. Our questions were answered in your opinion - NO, THEY WEREN'T, in bold font. C++/CX makes targeting WinRT easier - at the cost of not being C++. We have WRL - it is not fast and fluid.

    Here, all your points answered again. This is perhaps the third time they appear in the thread, same points, same answers. Nobody disputes 1-2, 4-5 are beside the point and not under any real dispute either, 3 is in the spotlight yet your way of defending it is to simply assert again and again and again that we've been given answers. In truth, all we've been given is unsubstantiated feelings along the lines that doing all in C++ is "possible, but not practical". Well, this might be enough for a school newspaper, but this is a technical site, so unsubstantiated feelings don't work. Even if they are expressed by celebrities like Herb Sutter.

  • @Charles please stop. This what you're doing (especially relinking well read by everyone threads) is actually insulting, arogant and makes me think that you're having a great laugh with other lads from MS on our (C++ community) expense. Either behave like a man or stop posting. And if you cannot understand what is asked simply say it and get someone (Jim perhaps) who is capable of doing so.

    Oh, and one more thing, could you please do not invite mr sutter anymore, as he proved on this thread that he is also incapable of reading long threads and understand what is asked in them. I think most people will agree with me that what mr sutter showed here was just pathetic and we just do not want to read/listen to what he has/wants to say anymore.

  • Aaron StainbackAceHack AceHack

    As someone who started with VB, then C#, and then moved to C++, I can say the Managed Extensions and C++\CLI extensions were great at bridging the learning curve gap between C# and C++.  I was really writing C++ that looked almost exactly like C# at first.  Then I was able to play and learn more "unsafe" C++ features one at a time and learn the advantages and disadvantages of each in isolation while still being productive.

    After getting very familiar with the amazing optimizations available in C++ it was disappointing that the CLI extensions compiled to the slower managed code.  So I did my best efforts to only use CLI at the boundary but in conjunction with WPF and a MVVM pattern this option ran into performance issues with huge amounts of data and it was tedious to keep all the boundary code in sync with the real code.

    That is why I am very excited to see C++\CX.  Since it compiles to native code many of the performance issues will now be eliminated.  I am very excited to see that as I considered that a minor drawback of C++\CLI.  The reason I didn't consider it a major drawback was because in most LOB apps I've worked on the amount of data on the screen at once is not a lot but it really affected scientific data visualization.  The Boundary layer was slow for huge amounts of data unless extreme optimizations were done that really obscured the code and took much time.  The other part of C++\CLI and still C++\CX I still consider a minor drawback is the lack of a built convention based model like the Entity Framework code first approach.

    EF uses certain "strategies" to map object concepts to DB table "resources", using a similar approach I created T4 templates that used the C++ ISO standard API as the code first for auto generating the wrapper non ISO C++\CLI classes.  This did require that I map basically the "resource" allocation "strategies" (implicit ownership rules) of the existing ISO API so the T4 templates could be generated off convention and this declarative "resource" strategy mapping.  I'm sure this is a naïve approach and would not work in all situation's but I've hacked together several T4s that basically describe the implicit "strategies" behind a few specific open source C++ projects so I would not have to keep the boundary layer in sync by hand.   So when the ISO API changes so does the C++\CLI Boundary layer automatically.  I took this approach specifically in a molecular biology software project that ran both on the Mac and Windows and used several cross platform C++ open source APIs for the back end while having a WPF front end on Windows and a Cocoa front end on the Mac.

    Overall I am very excited to see C++\CX and I think it will be warmly welcomed for the design goals it was intended to serve.  It would be nice to see some additional features that built upon C++\CX like the EF\T4 "resource" strategy mapping approach.  My templates are really hacked together but their do seem to be common strategies among C\C++ API open source projects that allow for code generation based off some common generic strategies.  I'm sure a more seasoned C++ could speak more on this subject.  Anyways thanks for all the hard work, VS11 is very exciting to me.

  • dbudbu

    @KMNY_a_ha
    >@dbu: Unfortunately must disagree with you.
    >People will buy it, people will use it. Just
    >because you, I and some other few people didn't
    >get the "WinRT thing" it doesn't mean anything
    >and MS knows about it. They will push with
    >stubbornity of a donkey every new technology
    >however badly designed. It doesn't matter -
    >they can afford it.

    Most of the C++ devellopers here are develloping
    classic desktop aplications. So WinRT doesn't give
    us anything we need.

    But what we need is, to support WinXP for at least
    5 years. And because VC11 doesn't support XP we have
    to do this with an outdated c++ compiler and outdated
    librarys for years!

    And we can't use the new C++11 features to improve
    our products for years and years, too.

    So don't tell me that VC11 isn't broken by design!
    For most of us it is.

  • dbudbu

    @hmm:
    >Charles, let's see what VC11 delivers for C++ developers.
    >1. No new C++11 features. (yeah in future, before VC12, when???)
    >2. Programs compiled with VC11 won't run on XP SP3 (statistics show
    >that XP is still the most used OS out there).
    >3. No modern desktop GUI libraries, except the one for metro (no one
    >cares about metro).
    >4. WinRT and C++/CX that is of no use to real C++ developers.
    >I don't think many C++ developers will be buying VS11. The only
    >thing VS11, compared to VS10, gives you is the lack of XP support
    >and 2-3 additional C++11 features. Surely Microsoft must know that
    >such steps will not be welcomed by C++ developers. But they're not
    >afraid of that, since their goal is to kill C++.

    you got it :)

    1. @dbu and would you mind and point me out to the place where I've stated that VS11 isn't broken by design!?!
  • GlenGlen

    @kmny

    You've heard Microsoft. Their plans are what they are. Everybody has made their grievances known now. It's Microsofts problem after that. Don't continue a dysfunctional relationship by arguing.

    Bjarne always says keep your code ISO and it's exactly because of situations like these.

    I don't intend to adopt anything new from Microsoft at this point. WinRT and C++/CX and the XP saga is a good point to break the cycle of MS dependence, not deepen it.

    If others find that its never been better to stay, I am happy for them, that is freedom of choice.

    clang 3.0 is coming along strong though and Embarcadero has a product line that is shaping up nicely, so it's never been a better time to leave too. Clang is allowing everyone to deliver some great code analysis, conversion tools and capable IDE's and there are now some really new and interesting platforms to target other than Windows.

    Sometimes the path just forks and you have to go your own way. If you are always ISO, you always can, just with a little harder work, but that's the price of freedom.

    I don't intend to let Microsoft make that job any harder. It's better to just focus on that, than spend time arguing here.

    People like PFYB have vanished, I doubt it's because they are off writing volumes of C++/CX. They will just not use this stuff. There's your answer.

    In the end, we didn't achieve a single thing in this thread. Isn't that the lesson itself? So it wasn't wasted. What more do you need to hear?

    I have no further expectations from Microsoft at this point, I am simply not looking to them to provide the answers now going forward. That's all there is to it.

    Good luck to everyone who joined the thread.

  • @Glen the only thing I'm saying that professional programmers will us VS11. Either they like it or not. What, you're thinking that company you work for will switch to differen compiler because you don't like it? Think again.

    And just to be clear: I do not agree with MS politics, behavior and plans for future (lack of C++11 expecially), but this doesn't change the fact that people will still use their product. For the same reason why they use Windows. And for the same reason why they use Office And talk to you few years from now you will see it for yourself.

    And perhaps the best example for you will be yourself and your company. Are they leaving Visual Studio? If yes then you're right, if not I'm right.

  • CharlesCharles Welcome Change

    @All: Enough. Everybody go home. Bar's closed.

    AceHack, thanks for the fresh air.
    C

  • GlenGlen

    @kmny

    I think what you are pointing out is that, for many, switching vendors is not easy and making that call to switch, often isn't down to just one person.

    If so, you are right. That's why many people feel stuck with Microsoft and angry at their policies, but are unable to get out and for the reasons you mention. There just wouldn't continue be all this heat if you were not right about that, so sorry if my comments seemed insensitive to that or appeared to gloss over that fact.

    I was just saying that, regardless, a time comes in any relationship when you what you want from an other is not what that other wants to give; and when you reach that understanding, or fail to, then continuing to argue for what you want, when it just isn't going to happen, is destructive and dysfunctional. Avoiding that, means at some point before then, argument needs to be replaced by more acceptance and planning for leaving.

    I was just suggesting that perhaps that time has come, but if you want to continue that fight and have the energy for it, good luck. I hope you win.

    I think its dysfunctional though now, this thread has shown that Microsoft just doesn't share the same vision of C++ that a significant number of the developers that use their C++ tools share. They haven't for a long time. If they did, this heat wouldn't be happening and so constantly, because it isn't happening anywhere else.

    When Microsoft first started talking of a "C++ renaissance", most people thought it meant exactly that - that Microsoft and C++ were coming back; that engaging with Microsoft might start to feel more like Boost or at least like how Microsoft used to relate to C++ prior to (and including) VC 6.

    However, that view is simply wrong. Charles has stated this is wrong several times over now in numerous posts to this very thread which anyone can look up.

    Even the names even say it all.

    Microsoft is about Going Native, Proprietarily, Eventually. Hence the Going Native name, the proprietary C++/CX and C++11 Eventually at a date still to be determined and in a quantity still to be guessed at.

    In contrast, Boostcon is now C++ now, cross platform, and standards orientated, yesterday, now and tomorrow.

    They are different paths with different masters.

    By all means continue to fight Microsoft, but the answer to your question is that the less tenacious of us are accepting this and instead using our energy to attain clang compatibility one file at a time, as we get chance, and staying clear of C++/CX, WinRT and WRL, at least until such time as Wg21 can come up with something that makes that deal more appealing if that day ever comes.

    (BTW. How many people have to keep saying WRL isn't an answer before MS stop quoting it as a solution?)

    Anyway, how about we propose features for C++15 instead, rather than waste any more of our time flogging this dead horse? I think I linked the cpp-next thread on that previously.

    Maybe Herb can contribute his list. await seems like a good start. Any improvements to that?

  • MeMyselfAndCppMeMyselfAnd​Cpp


    I've followed this thread from top to bottom and in the end I think it was productive at least to get Herb and Jim insights.

    I have to leave a comment on all the unsupporters of C++/CX that I truly don't get it. For one of the proposed solutions was talking about declspec and #pragma this would also be talking about proprietary compiler extensions. Even if I had a totally library solution we are talking about targeting a specific platform, so where’s the gain, not expecting to WRT on Linux anytime soon. So let’s wait for Tomas solution since is determined to put is code where is post are .

    @Charles:
    I would appreciate that you could get some of these topics cleared for me, in a future issue of GoingNative or other.
    I was and still am a user of COM, (yes still better solution than DLLs with C Exports or C++ Exports) and in the end COM will always be Love. But, it also comes to mind some flaws it has, let me put just some questions out there:
    • How are Interface versioning being handled?
    • “GUIDs are gone” so I’m guessing you are hiding the GUIDs through the use progid’s. If this is true, has the size limit been increased? And colliding progid’s how are they handled?
    • We will be probably mostly be using Registration Free Activation, but some sort of “GAC” will exist. This “GAC” is still managed by the registry.
    For some time I though native development was dead (in terms of Windows anyway). And now I see a lot of it and I like it. Though I would like to understand why this shift in focus in Microsoft. Herb hinted this with the “Performance/Watt talk”, but as Rico Mariani as shown (http://blogs.msdn.com/b/ricom/archive/2005/05/20/420614.aspx ) in the past in his “completion” with Raymond Chen out of the gate C# is not as slow as we native developers tend to think. But it also shows a tradeoff of speed versus resource consumption.

  • DennisDennis

    Oh...

    > Even if I had a totally library solution we are talking
    > about targeting a specific platform, so where’s the gain,
    > not expecting to WRT on Linux anytime soon.

    According to this logic, let's have a language extension for each new API created by Microsoft folks. Let's also have a new language extension for each new API created by Linux folks, by Apple folks, by whoever really.

    Seriously, do we really have to go into why exactly is it that the standards are important?

  • @Glen, that's my point exactly - it is very hard to switch to another compiler if you have large code base and I'm sure MS is aware of that. What I see and what I understand from this and few other threads is that we (C++ community) are with master-slave relationship when comes to Microsoft. And as long as this will continue there are always going be attempts to brake the chains and be free!

    C++ Rules And Rocks!

    Forever!

    @ me_myself_and_cpp: From: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2059755-move-forward-and-bring-back-vs-ui-written-in-nativ?page=3 "The only reason Raymond had several post instead of just one was that he intended to show his toy program evolving over time. Nor was the sequence of blog posts an example of just how well .NET performs. Raymond was *not* trying to outperform C# code put by Rico. Rico did try to outperform C++ code put by Raymond, without too much success. That's it."

    When people will get it?

     

  • GlenGlen

    @MeMyselfAnd​Cpp, hello! Great comments.

    Nice to have some pro COM people other than MS to debate with. Thank you.

    First, what I think we agree on. You said:

    "Even if I had a totally library solution we are talking about targeting a specific platform, so where’s the gain, not expecting to WRT on Linux anytime soon."

    Exactly. That's why WRL is a waste of time and why MS has been invoking my ire. Why would anyone ever do WRL? They wouldn't, for exactly the reasons you stated. Please explain that to Charles because that is exactly why WRL should never be mentioned again and why Herb/Jim etc. rightly came up with an alternative that is far better than WRL as far as it goes.

    This isn't to knock WRL either, but it needs to be known that its really just a political solution to appease people who are missing the truth of your statement. So Ms should stop promoting it as it really is inviting people down a road they shouldn't go for the reasons you've said.

    Regarding your COM questions, great questions, I'm keen to hear the answers. Thanks for asking them.

    Now on the bits I'd like to debate with you further: "COM is Love".

    The drum I've been trying to beat with Microsoft is that COM is still too hard and too niche as it stands.

    My constructive questions to you that MS don't engage on, are these:

    1. If COM is the answer, I haven't heard anyone outside of Microsoft say that it is. Why? And is that going to change and why? If it doesn't, we shouldn't persue it, nothing niche has a future. MS has a history of short term, dead end, technologies.

    2. For COM to succeed for C++, even more steps need to be taken to make C++ a better fit for it. What further can you suggest?

    3. How do you feel about ref class ever becoming standard? If it doesn't, isn't that forking the C++ user base so badly that it harms C++? Isn't that reason enough to eschew ref classes.

    4. See my long post earlier on "C++ good for writing libraries". I've really had no one get into the meat of that post. Please pull it apart and attack it, agree with it, or expose whatever you see as errant in that. I'd be keen to know your opinions. The comments I have made in that post are what I see as the future life of the C++ programmer on Windows. Do you agree with that. Do you want that? Don't you think we can do better? C# avoids all this. Wont more people defect to C# because of it that shouldn't need to.

    I don't intend to use C++/CX and WinRT as things stand myself, but nor am I interested in fighting MS over it any further, but I am keen to see others promote its merits that are non MS. This camp has been remarkably quiet until now, so I'm pleased to see the inputs coming in. I still want what is on offer to improve.

    Man this thread is long, we need another thread! lol

    Thanks :)

  • LostInSpacebarAdityaG OMG VISTA FTW LOLZ!!1one

    * Almost do fist bump * "We can't do this man, or we'll destruct" <3 lol

  • TomasTomas

    Hi guys
    I am finally here with my attempt to access WinRT without CX extensions and Platform::Strings. I must say sorry if you waited for me it took me too long but I recenly changed my job and moved to another country for work so you can imagine my head is full of different stuff right now.
    For everybody interested in my approach which is the same approach discussed by many smart people here take a look at http://code.google.com/p/winrt-wrapper/source/browse/. There is a readme.txt with some technical details and all the source code. The code although quickly baked is working well with only one issue at application exit (read the readme). Feel free to dig it yourself. After I have gone through this I must say I am not convinced by the necessity and usefulness of CX extensions at all. Quite on the contrary I see I can program WinRT applications without all the crazy stuff the way I like the way I am used to.

  • WarrenWarren

    Nice to hear from you, Tomas!

    I took a look at your code and I have to say it does look pretty clear and straightforward. Good job. Me and my team did our own experiments with WinRT and the code we were working with was in many aspects similar to yours. There is a small core of helper classes and then there is a huge mass of uncreative boilerplate for each class you want to use in your application, perfectly suitable for generation by an automatic tool.

    I completely agree with your conclusion:

    > After I have gone through this I must say I am not
    > convinced by the necessity and usefulness of CX
    > extensions at all. Quite on the contrary I see I
    > can program WinRT applications without all the crazy
    > stuff the way I like the way I am used to.

    Exactly!

    Charles, any comments from you? You seemed interested in what Tomas would come up with...

  • Followed this thread since the beginning. Now that Tomas posted some sample code, I wonder what Herb and Jim (and everyone else that has been posting here) have to say about it.

  • CharlesCharles Welcome Change

    Nice to hear from you, Tomas!

    I took a look at your code and I have to say it does look pretty clear and straightforward. Good job. Me and my team did our own experiments with WinRT and the code we were working with was in many aspects similar to yours. There is a small core of helper classes and then there is a huge mass of uncreative boilerplate for each class you want to use in your application, perfectly suitable for generation by an automatic tool.

    I completely agree with your conclusion:

    > After I have gone through this I must say I am not
    > convinced by the necessity and usefulness of CX
    > extensions at all. Quite on the contrary I see I
    > can program WinRT applications without all the crazy
    > stuff the way I like the way I am used to.

    Exactly!

    Charles, any comments from you? You seemed interested in what Tomas would come up with...

    My thoughts? OK. But take them with with a grain of salt or two.

    I like the wrapping of WRL approach, as we've discussed - WRL is the lowest level C++ abstraction for WinRT, but you could write a C-based solution, if you want to go even lower. WRL is a means by which you write C++ components for WinRT, too, as we've covered. Now, you want to share these object across foreign language and execution boundaries, sometimes. This requires extra work when you go the WRL route with wrapper interfaces and hand-written boilerplate. The automation story at play for the masses is C++/CX. ^s and refs are the friendly abstractions in this case. A different approach, yes. It's the one we're going out with in Dev11.

    Tomas, thank you for putting code where your mouth is. Nice job. Keep on exploring and let us know what you discover along the way. What will you find as you go deeper into the rabbit hole?

    C

  • @Charles, you didn't get it again. And frankly speaking I don't think that any of you (MS guys) neither want nor care to get it. The point Tomas made is that everything what's needed in order to cooperate with WinRT is easily achievable just by using pure, standard conforming (ISO C++ standard - that's for mr sutter specially, for it was only he who seems not to understand what standard is important for C++ community) C++. No foreign extensions are neither needed nor necessary. CX is a stupid looking guy on the job who doesn't really needs to be there (nor knows any better how to do this particular job) but his dad has connections so they employed him.

    Short story - there is absolutely no need for CX - C++ already provides everything and more in order to allow efficient interacting with WinRT - proved by Tomas.

    @Jim, Jim when you were saying in one of your posts that before CX came to live and people where thinking about its desing, someone in the room said, why not to use CLI syntax, and everyone started laughing at him, wasn't that mr sutter who said that?

    And last note: Charles, you're wrong again, C doesn't let you go lower than C++, they are allowing you to reach exactly the same level, they just provide different levels of abstraction.

    When will they learn?

  • WarrenWarren

    Charles, I don't want to be unnecessarily confrontational, so I will just quote the entire exchange.

    Here is what you said previously about Tomas endeavour:

    > We also appreciate what Tomas is trying to do - in code,
    > not words. We've already said it's [using standards-compliant
    > C++ instead of C#] possible, just not practical.
    > Perhaps Tomas will learn that.

    Cool. Repeating this one more time: perhaps Tomas will learn that doing it all in standards-compliant C++ is possible, but not practical. Your words, Charles.

    Tomas does the work, returns and says:

    > After I have gone through this I must say I am not
    > convinced by the necessity and usefulness of CX
    > extensions at all. Quite on the contrary I see I
    > can program WinRT applications without all the crazy
    > stuff the way I like the way I am used to.

    Does it sound like Tomas learned that doing it all in standards-compliant C++ is possible, but not practical? No, it sounds like he learned that exactly the reverse is the case!

    So, Charles, what is your reaction to this, I ask?

    Your answer:

    > Tomas, thank you for putting code where your mouth is.
    > Nice job. Keep on exploring and let us know what you
    > discover along the way. What will you find as you go
    > deeper into the rabbit hole?

    You disregard everything Tomas says, suggest that he keeps on exploring, and imply that he didn't go into the "rabbit hole" deep enough.

    This is just dishonest.

    +1 to KMNY, too.

  • CharlesCharles Welcome Change

    @Warren: Sorry if I seemed belittling. It wasn't my intention. I think it's great that Tomas spent the time investigating and coming up with a solution using code. I also think it's a solution we've discussed (wrapping WRL) - but Tomas demonstrated it. Right on.

    The moral of the whole story here is: you don't like the C++/CX solution to the problem and you don't think it's the best solution. We've acknowledged that this is fair. We respect that. We've also been very clear that C++/CX will be the solution that ships. You can manually program WinRT with C++ using WRL (people do this today...). What else do you really want to talk about? I'd wait for Jim to stop by to critique Tomas' solution and not use my reply as anything other than my reply... You asked. I answered. Jim and team are heads down writing code that will ship at some point. They're very busy right now. I don't think a reply is imminent.

    And, I do get it. I looked at what Tomas has come up with - thank you for spending time on this, Tomas! - and I stand by my commentary on the matter, minus the belittling remarks, which were unintentional. I don't disregard anything in his solution - it's the one we've been taking about (wrapping WRL).

    Let's agree to disagree and move on. The solution we'll ship is C++/CX and a small template library for exception-free WinRT programming in C++.

    C

  • WarrenWarren

    Charles

    Argh... I will give this one more try.

    > And, I do get it. I looked at what Tomas has come
    > up with - thank you for spending time on this,
    > Tomas! - and I stand by my commentary on the matter,
    > minus the belittling remarks, which were unintentional.
    > I don't disregard anything in his solution - it's the
    > one we've been taking about (wrapping WRL).

    Please take one more look at Tomas's code.

    The files in \trunk are specific to the application. The files in \trunk\Generated are not specific to the application and are the interop layer for WinRT. The amount of code in the interop layer is 5 times the amount of code in the application itself. Admittedly, this is a simple demo application, but the interop layer does not come even close to covering the entire WinRT either. To cover the entire WinRT, the interop layer would have to grow at least by a factor of 20. Take note though that all code in the interop layer except maybe Object.i.cpp and Object.i.h is boilerplate code. It can be generated by a tool.

    The point of Tomas's experiment was to try and use WinRT from C++ using code that could have been generated by a tool, to check if this looks feasible or not. Did he succeed? Yes, and Tomas says so. Quoting Tomas:

    > After I have gone through this I must say I am not
    > convinced by the necessity and usefulness of CX
    > extensions at all. Quite on the contrary I see I
    > can program WinRT applications without all the crazy
    > stuff the way I like the way I am used to.

    You don't have to take Tomas's word either, you can look into the code in \trunk\Generated and see that it: a) works, b) is tedious and too bulky to write manually every single time you need it, c) can be generated by a tool. The point has been made. Using WinRT from C++ via wrapper objects that could have been generated by a tool does look feasible. To the extent Tomas was willing to carry his practical experiment he did not encounter any significant setbacks.

    So, Charles, how can you "stand by your commentary on the matter", when you commentary was that the solution with wrapper classes was imaginary and speculative and Tomas's code shows that, indeed one can write these wrapper classes, they can indeed work, it indeed looks that they can be generated by a tool, and so on?

    How can you say that you "don't disregard anything in his solution" when you ignore the actual point of the experiment, which was to check if the approach with wrapper classes looks feasible, and pretend that it was about whether or not one can use WRL?

    Please tell us.

  • CharlesCharles Welcome Change


    Argh... I will give this one more try.

    I'm growing really tired of this. You make it seem like I just don't understand what's been said over and over and over again here. I DO. Let me say this to you one more time: We are not going to provide this model for you. You'll need to do it yourself - like Tomas has done.

    Please take one more look at Tomas's code.

    I did. He wrapped WRL as part of his solution. He's shown that you can write WinRT apps in ISO C++ using class abstraction. As I said (in each of my posts on the matter: GREAT!!). His experiment is not a complete solution nor did he advertise it as such - it's a proof of concept and he's shown, again, that you don't have to use C++/CX to write WinRT apps in C++.

    To the extent Tomas was willing to carry his practical experiment he did not encounter any significant setbacks.

    To Tomas, keep exploring and keep experimenting. Make a shared ISO C++ WinRT object and consume it from JavaScript. Consume a C# object from your ISO C++ WinRT application. See how far you can take this. Of course, there will be a lot of boilerplate code to write, as you know (and as we have said).

    So, Charles, how can you "stand by your commentary on the matter", when you commentary was that the solution with wrapper classes was imaginary and speculative and Tomas's code shows that, indeed one can write these wrapper classes, they can indeed work, it indeed looks that they can be generated by a tool, and so on?

    Yes. My commentary was essentialy "Great. Keep exploring. You may run into a wall of complexity that prompted the C++/CX decision...". We've made it clear from day 1 that: You don't have to use C++/CX. You'll need to write a lot of code when go the WRL route, including the "wrapper class" aproach as Tomas has shown. That's the way it is. No need to keep saying this over and over again.

    How can you say that you "don't disregard anything in his solution" when you ignore the actual point of the experiment, which was to check if the approach with wrapper classes looks feasible, and pretend that it was about whether or not one can use WRL?

    When this was first mentioned on this thread, it was acknowledged that this approach is feasible, but not practical and not in line with a primary goal of developer productivity (lots of COM boilerplate code is generated by the front-end compiler running over C++/CX code, winmd files are autogenerated, etc,etc... - the CX extension and associated toolchain are built specifically for WinRT, a single ABI that runs on a single platform.........).

    Please tell us.

    I did. I can't make it any clearer: C++/CX and WRL are what will ship in VC11 for writing C++ objects for WinRT. If you don't want to use C++/CX (or can't depending on your situation - can't use exceptions, etc...), then don't. Use WRL and handroll your own WinRT-specific boilerplate code. A solution like Tomas' plus some infrastructure support (code gen) will not be provided (not in this release, if ever - I don't know. I don't work on the VC team.). There is no need to keep going over this point. Please stop.

    Finally, thanks to all of you for the honest and open dialogue. My apologies if I seem frustrated, but I am. This thread has come to an end. Let's all move along.

    C

  • WarrenWarren

    Charles, you keep dodging the point.

    > When this was first mentioned on this thread, it was
    > acknowledged that this approach is feasible, but not
    > practical and not in line with a primary goal of developer
    > productivity ...

    Tomas did the experiment to try and check whether or not this is the case. His conclusion is that - to the extent he was willing to carry the experiment - the approach was both feasible and practical. What is it in Tomas's code that is not practical? What is it that is not "in line with a primary goal of developer productivity"? Are you saying the approach will break if Tomas tries to "make a shared ISO C++ WinRT object and consume it from JavaScript"? If so, say it.

    You keep saying things you can't back up. This is exactly the reason everyone here, including you, is frustrated.

    If Herb and Jim and you either would have shown WHY wrapper classes wouldn't have worked (just so that we don't waste another pair of posts clarifying this trivial point, Charles, this means: would have been both feasible and practical to implement) OR agreed that wrapper classes would have worked, the thread would have likely ended at that point. As it stands, you can neither substantiate your arguments, nor admit that - oh, the horrors - C++/CX was a mistake. So the thread continues.

  • KurtKurt

    @Warren: You won't get Charles to say anything besides what he is saying now. No matter the arguments, Charles is here to say good things about Microsoft technologies. Yes, it absolutely looks that C++/CX was a grave mistake. Wrapper classes are a much better solution. Thanks a lot to you, Tomas, KMNY_a_ha, Glen, Dennis, PFYB and other folks on the thread for making that point very eloquently. But Charles will never admit it. He can't, his entire job is to say that C++/CX is cool.

  • Nicholas BNicholas B

    God. what a thread! I just found it today and couldn't stop until I read it all.

    I have to say I side with those who think that C++/CX was a mistake. WinRT should have been kept outside the language. Since the message from Microsoft seems to be that C++/CX and WRL are what will ship in VC11 and that even if wrapper classes make more sense, Microsoft don't care, here is a message from myself - in this case, I don't care to use WinRT from C++. You make us jump through hoops to use your new API from our language, you see how far that API will go in the C++ world. I will just use Javascript.

    To all the participants - thank you for a very informative thread.

  • TuumeTuume

    I have been watching the thread since the beginning. Charles, your opponents are exactly right, you keep answering questions noone is asking. I don't mean to say you are doing this intentionally, but in effect it looks like you are dodging the original questions.

    The area Tomas set to explore was about the approach with wrapper classes, not WRL, not anything else. The conclusion was that wrapper classes work - to the extent explored by Tomas. Your original response was "I like the wrapping of WRL approach, ...", completely off point. You now say that your response is "Great. Keep exploring. You may run into a wall of complexity that prompted the C++/CX decision...". But Tomas says he didn't run into any walls. Are you saying he will run into a wall? If this is what you want to say, then please stop being all vague and hinty and say it clearly. Please explain to us what this wall is. Don't just say this wall exists somewhere, please show it. Tomas and others like PFYB and Dennis put their money where their mouths were, do the same please. You are trying to feed us stories of the proverbial wall for more than 200 posts now. Your opponents have been looking for this wall for months, they are dying to know what it is. Several people have written prototype code, Tomas even shared his code for everyone to look. They went to great lengths to try and find the wall you keep talking about. Please show us some courtesy and reply in kind, tell us where the wall is.

    Finally, I'd urge all commenters in this thread to look at CXXI here: http://tirania.org/blog/archive/2011/Dec-19.html. This is very similar to the approach with wrapper classes (wrapping C++ classes to expose them to non-C++ clients) suggested in the thread. The Mono developers considered this approach to be both feasible and practical for their thing.

  • CharlesCharles Welcome Change

    All, I am only trying to say that C++/CX is the approach we have taken, regardless of what Tomas has shown (and I like the fact that he's done something to show a different approach, this is the power of C++ and C++ developers).

    Since I am not on the C++ team - and quite frankly, I should not have spoken on their behalf - I will not speak to why approach A was chosen over B (Herb and Jim have already explained the reasoning here - and that's enough). C++/CX and WRL are what will ship and they're excellent tools for the job at hand. People are building apps with them today and the consensus is overwhelmingly positive.

    This conversation needs to end now. So, it will.

    C

  • GlenGlen

    @Charles

    Thank you for re-enabling this thread. As noted, no reply expected. :)

    I am glad you have accepted that extreme censorship is not the answer though.

    @KMNY, Charles has re-opened this thread as I asked so that we can just burn ourselves out or whatever in a naturual way. Can you respect that please. I support the basic essence of some of the things you were saying, but you say things far too strongly that it almost rises to hate speech IMHO. For example, you are not alone in thinking some of Herb's replies were not his best, but words like snake, cretin and traitor are over the top and don't credit him with the respect he deserves. Frankly, I just don't enjoy reading that kind of language if you are right or not. It is beyond keeping it real. You asked.

    I asked for this thread to be re-opened in the name of free speech. For myself, I don't have more to say *to Microsoft* about C++/CX (other than by accident by finding it hard to keep ones mouth shut some times at some of the statements); since I *accepted* some time ago that Microsoft is sticking to their current plans. I encourage others to accept that fact too. I am of course interested in what the rest of you have to say and I wanted to thank @Tuume's for his link to CXXI. I don't find it off topic at all myself.

    Even if it were, I think freedom of expression dictates we allow for a level of somewhat off topic opinions. Trying to cut down every off topic statement is too controlling for my tastes. Things have a natural way of going where they are meant to and for revealing what what is bubbling under that needs to be said or might get missed.

    Otherwise, this would be a one way MS sales pitch and if it were that, I wouldn't read any of it. So its a case of taking the rough with the smooth. I hope Microsoft concedes some of these ideas.

    Thank you everybody for your contributions and for the recent posts from Tuume, Anne, TQR and Warren. Thanks to Charles again for seeing the sense.

  • @Charles Just to correct you because you're wrong (again) in what you're saying:

    "C++/CX and WRL are what will ship and they're excellent tools for the job at hand."

    Charles by saying this you just contradicted yourself. At one point in time you've said that WRL approach is feasible but impractical, now you're saying that they're excellent tools. Well I suppose that's how the regime's machine works.

    And when you're saying: 

    " People are building apps with them today and the consensus is overwhelmingly positive. "

    Would you mind and point us to the place where people are actually expressing their positive opinions on a subject? Somehow they're not here.

    And could you also ask mr herb to tell us what university he finished, what titles he has, what is his qualification/education background. Looked on the web, couldn't find anywere. But surely he must have (not some) education in the field, he poses as an expert mustn't he?

    So just to summarize:

    1. WRL is not an excellent tool even thoug once you say it is and few days after you say it isn't and few days after that you say that it is. Get it!

    2. Where are those people who think CX is a great tool for a job?

    3. What is a FORMAL education of mr sutter.

    Cheers

  • Anna LeeAnna Lee

    Glen, thank you for managing to convince Charles to unlock the thread, locking it was crazy.

    Just in case something happens with KMNY_a_ha (LOL), here are his first two points slightly paraphrased:

    KMNY 1. Arguing like Charles does that WRL is both (feasible but) impractical and excellent is strange.

    KMNY 2. Where are those people who think CX is a great tool for a job? We aren't seeing any.

    I support both points.

    On CXXI, thanks a lot to whoever mentioned it first. I have been looking into it ever since, I feel I learned quite a lot. Since the sources for CXXI are openly available (pure love!), one obvious idea would be to adopt the part that parses C++ and emits C#-XML to emit C++ wrapper classes for WinRT. I personally likely won't spend any time on this, since I think the whole of WinRT is a failure, but the possibility is definitely there.

  • GlenGlen

    @Anna, I agree CXXI looks great and I thought the same as you there.

    Clever guys, on more than one level too, as what I'm about to link will show!

    @kmny, from the previous blog, you said:

    "If to you all of those things are just a language and you can easily switch from one way to other and you accept that from now on someone will tell you what language you have to speak in order to be understood, then Glen, we are made from very different clay".

    If you look back, you will see I have supported the gyst of a good number of your statements, and especially the one above. I could have written it myself.

    However, language is of no use if you can't control it to be understood too. You still need perspective, or you aren't talking clay, you are talking doggie chocolate!

    I've argued on occasion with Herb and Charles in pretty blunt ways myself, but words like traitor, cretin, snake *on a near continuous basis* is too much. Now you are pressing Herb for formal qualifications? Come on! Like they matter when his track record is as obvious as it is? Like he needs to prove them to you or me anyway? More to the point, why would his qualifications appease you anyway given your feelings? I doubt they would, so why pester for it?

    Lest we forget, there are qualifications you don't always get at school anyway. This is for all of us at times, but today, this is for you KMNY:

    http://tirania.org/blog/archive/2011/Feb-17.html

    Do follow the very descriptive links too!

    That Miguel, he does come up with the gems!

    KMNY, I hope you reign yourself in as you make it hard to support you otherwise. I'd hate to see you get banned or the day I'd want you to see you banned. Characters are core to a good debate but we do need some lighter moments too.

    I'll offer no more comment on the subject. You have my best reading on the matter and thanks for it go out to Miguel!!

    Happy Holidays!

  • @Ann thank you for paraphrasing my post. Most appreciated. Thank you.

    @Glen Thanks for the link.

    Now to answer your queston:

    I'd like to see mr sutter's qualifications because his "track record" as you called it, so far is just that he can talk a lot - but does very little actual real work. And from this link (given to me by PFYB) http://herbsutter.com/2011/10/25/garbage-collection-synopsis-and-c/ you'll see that he has actually very little idea what he is talking about. Concentrate on exchange between him and David Abrahams.

    And why do I want to know what mr sutter's formal education is? Because I'm fed-up with careerists like him, who without proper education are put on absolutely unsuitable positions and are absulutely unprepared to do any real work - because they don't have right/correct education. That's why.

    And as my feeling goes, mr sutter doesn't have formal education which would indicate that he is a suitable guy to be a C++ architect. But I'm happy to say that I was wrong only someone has to prove it to me. But he wan't. Becase he can't. Because he doesn't have anything to show except smart * responses and patronizing talk. That's what his track record is so far.

    As for my language, first, have to correct you here, I've never called anyone cretin, you see Glen, you just repeating what Charles told you, without actually paying attention what I'm saying and why. Anyway, that's not important. The important thing is that I believe that in extreme situations extreme measures are needed. This is extreme situation. That's why I'm using the kind of language I'm using. I'm not going to say to someone when he lies to me that his truth is different to mine. No! He is a lair. In case of mr sutter when at his position, he did nothing to help C++, on the contrary it seems like everything is done to hurt C++, what in that situation mr sutter should be called? The guy who tried to kill C++? I'm ok with that too.

    And I'm sorry to say Glen but if you cannot overcome the negative feeling and see truth in my words just because I'm using strong language, then just simply don't read my posts. It's easy I think. You see my nick and skip it.

    But I tell you one thing with reference to that - I and II war could've been avoided if diplomacy hadn't been used.

    And if I'll get blocked from this site it will just prove my point more than anything.

    I'd like you also to clarify on that, becase well, it is not clear what you mean when you say:

    "However, language is of no use if you can't control it to be understood too. You still need perspective, or you aren't talking clay, you are talking doggie chocolate!"

    Regards

  • FitzFitz

    Just read this entire thread and never saw the obvious answer.

    Think about it. C++ IS a system level language. You could write everything MS sells in it. I've written apps and drivers in it for every version of Windows since 3.1.

    I also wrote firmware in it for one of the first USB devices ever plugged into a Win95 machine (Oem 2.1 perhaps?)

    Anything the processor can do, C++ can do. If you can't write an easy to use binding layer to something running on a cpu in C++ without altering the language, there are only two possibilities.

    1. Stupidity
    2. You want to change the language

    WHY did MS fight so hard to make DirectX king over Opengl? Seems like a duh question to me.

    Why would making a standardized language that can run on virtually anything Ms playground specific be any different?

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.