Hello; I’m James McNellis, and I’ve recently joined the Visual C++ team as a libraries developer. My first encounter with the C++/CX language extensions was early last year, while implementing some code generation features for the Visual Studio 2012 XAML designer. I started off by hunting for some example code, and it suffices to say that I was a bit surprised with what I first saw. My initial reaction was along the lines of:
“What the heck are these hats doing in this C++ code?”
Actually, I was quite worried; because I thought it was C++/CLI—managed code. Not that managed code is bad, per se, but I’m a C++ programmer, and I had been promised native code.
Thankfully, my initial impression was uninformed and wrong: while C++/CX is syntactically similar to C++/CLI and thus looks almost the same in many ways, it is semantically quite different. C++/CX code is native code, no CLR required. Programming in C++/CLI can be very challenging, as one must deftly juggle two very different object models at the same time: the C++ object model with its deterministic object lifetimes, and the garbage-collected CLI object model. C++/CX is much simpler to work with, because the Windows Runtime, which is based on COM, maps very well to the C++ programming language.
Windows Runtime defines a relatively simple, low-level Application Binary Interface (ABI), and mandates that components define their types using a common metadata format. C++/CX is not strictly required to write a native Windows Runtime component: it is quite possible to write Windows Runtime components using C++ without using the C++/CX language extensions, and Visual C++ 2012 includes a library, the Windows Runtime C++ Template Library (WRL), to help make this easier. Many of the Windows Runtime components that ship as part of Windows (in the Windows
namespace) are written using WRL. There’s no magic in C++/CX: it just makes writing Windows Runtime components in C++ much, much simpler and helps to cut the amount of repetitive and verbose code that you would have to write when using a library-based solution like WRL.
The intent of this series of articles is to discuss the Windows Runtime ABI and to explain what really happens under the hood when you use the C++/CX language constructs, by demonstrating equivalent Windows Runtime components written in C++ both with and without C++/CX, and by showing how the C++ compiler actually transforms C++/CX code for compilation.
Recommended Resources
There are already quite a few great sources of information about C++/CX, and I certainly don’t intend for a simple series of blog articles to replace them, so before we begin digging into C++/CX, I wanted to start with a roundup of those resources.
First, if you’re interested in the rationale behind why the C++/CX language extension were developed and how the C++/CLI syntax ended up being selected for reuse, I’d recommend Jim Springfield’s post on this blog from last year, “Inside the C++/CX Design”. Also of note is episode 3 of GoingNative, in which Marian Luparu discusses C++/CX.
If you’re new to C++/CX (or Windows Store app and Windows Runtime component development in general), and are looking for an introduction to building software with C++/CX, or if you’re building something using C++/CX and are trying to figure out how to accomplish a particular task, I’d recommend the following resources as starting points:
-
Visual C++ Language Reference (C++/CX): The language reference includes a lot of useful information, including a C++/CX syntax reference with many short examples demonstrating its use. There’s also a useful walkthrough of how to build a Windows Store app using C++/CX and XAML. If you’re just starting out, this would be a great place to start.
-
C++ Metro style app samples: Most of the C++ sample applications and components make use of C++/CX and many demonstrate interoperation with XAML.
-
Component Extensions for Runtime Platforms: This used to be the documentation for C++/CLI, but it has since been updated to include documentation for C++/CX, with comparisons of what each syntactic feature does in each set of language extensions.
-
Hilo is an example application, written using C++, C++/CX, and XAML, and is a great resource from which to observe good coding practices—both for modern C++ and for mixing ordinary C++ code with C++/CX.
-
Building Metro style apps with C++ on MSDN Forums is a great place to ask questions if you are stuck.
Tools for Exploration
Often, the best way to learn about how the compiler handles code is to take a look at what the compiler outputs. For C++/CX, there are two outputs that are useful to look at: the metadata for the component, and the generated C++ transformation of the C++/CX code.
Metadata: As noted above, Windows Runtime requires each component to include metadata containing information about any public types defined by the component and any public or protected members of those types. This metadata is stored in a Windows Metadata (WinMD) file with a .winmd extension. When you build a Windows Runtime component using C++/CX, the WinMD file is generated by the C++ compiler; when you build a component using C++ (without C++/CX), the WinMD file is generated from IDL. WinMD files use the same metadata format as .NET assemblies.
If you want to know what types have been fabricated by the C++ compiler to support your C++/CX code, or how different C++/CX language constructs appear in metadata, it is useful to start by inspecting the generated WinMD file. Because WinMD files use the .NET metadata format, you can use the ildasm tool from the .NET Framework SDK to view the contents of a WinMD file. This tool doesn’t do much interpretation of the data, so it can take some getting used to how it presents data, but it’s very helpful nonetheless.
Generated Code: When compiling C++/CX code, the Visual C++ compiler transforms most C++/CX constructs into equivalent C++ code. If you’re curious about what a particular snippet of C++/CX code really does, it’s useful to take a look at this transformation.
There is a top-secret compiler option, /d1ZWtokens, which causes the compiler to print the generated C++ code that it generated from your C++/CX source. (Ok, this compiler option isn’t really top secret: Deon Brewis mentioned it in his excellent //BUILD/ 2011 presentation, “Under the covers with C++ for Metro style apps.” However, do note that this option is undocumented, and thus it is unsupported and its behavior may change at any time.)
The output is intended for diagnostic purposes only, so you won’t be able to just copy and paste the output and expect it to be compilable as-is, but it’s good enough to demonstrate how the compiler treats C++/CX code during compilation, and that makes this option invaluable. The output is quite verbose, so it is best to use this option with as small a source file as possible. The output includes any generated headers, including the implicitly included <vccorlib.h>
. I find it’s often best to use types and members with distinctive names so you can easily search for the parts that correspond to your code.
There are two other useful compiler options, also mentioned in Deon’s presentation, which can be useful if you want to figure out how class hierarchies and virtual function tables (vtables) are laid out. The first is /d1reportAllClassLayout, which will cause the compiler to print out the class and vtable layouts for all classes and functions in the translation unit. The other is /d1reportSingleClassLayoutClyde which will cause the compiler to print out the class and vtable layouts for any class whose name contains “Clyde” (substitute “Clyde” for your own type name). These options are also undocumented and unsupported, and they too should only be used for diagnostic purposes.
Next Up…
In our next article (which will be the first “real” article), we’ll introduce a simple C++/CX class and discuss how it maps to the Windows Runtime ABI. The following is a list of all of the articles in this series that have been published so far:
- C++/CX Part 0 of [n]: An Introduction [This Article]
- C++/CX Part 1 of [n]: A Simple Class
- C++/CX Part 2 of [n]: Types That Wear Hats
- C++/CX Part 3 of [n]: Under Construction
- C++/CX Part 4 of [n]: Static Member Functions
Just curious, does that mean there are now *2* people working as library developers? Although great to know a well known SOer is on the team. :)
Oh, goody. We have the same non-standard, unportable syntax extensions only now they mean something completely different. And you're thankful for this?
As has been proved in the post I provide link to, C++/Cretinus eXperimentus was not needed, syntax was crafted for the .NET crowd, C++ devs were nowhere in the picture while this totally unnecessary MUTATION, yes, MUTATION not extension was designed, and now we (C++ devs) are told to be greateful. What a joke!
Here is the link (mostly pay attention to exchange between Jim Springfield and PleaseFixYourBugs):
Why Cretinus eXperimentus proved to be pointless:
blogs.msdn.com/…/10228473.aspx
Guys: I don't understand your negative attitude toward C++/CX extensions. You can still use standard C++ with WRL, but the code you have to write with this WRL library solution seems to me more complex than the code you write using C++/CX.
And using "portability" as an argument for standard C++ in this case does not make sense, since you are targeting a specific platform (Metro/WinRT), so you don't care about cross platform in this case.
After all, C++ is an "extension" to C: you can still write virtual functions with v-tables, function pointers, etc. in pure C, but you have to write lots of boilerplate code; having the "virtual" keyword available in the C++ language helps a lot in writing simpler code. To me, the same applies for C++/CX and WinRT programming: when the code becomes very complex and boilerplate (the case of C++ with WRL), then this is a red-flag that maybe some "extension" to the language is required to make the code simpler again (in this case C++/CX).
And you can still use pure C++ in the remaining part of the app/component; C++/CX is just for the boundary.
@GiovanniD As explained in the link I've provided in my previous post, CX was not necessary, the same can be done using std C++ constructs, and those constructs DO NOT HAVE TO BE MORE COMPLICATED than CX Mutations. The point is that everything could be done with C++ while preserving maintainability of code and not having boilerplate code – this topic was already discussed between herb sutter and PleaseFixYourBugs, where herb sutter argued that C can be used for everything and C++ is unnecessary – THIS IS NOT THE CASE with CX. CX mutation has been invented purely for .NET crowd to suit their habits. There was number of discussion which prove this point, I don't have link for them but if the need be I'll find them. Just to point you out if you'd like to check them for yourself and see arguments on both sides (which always ended with silence and embarrasment on CX side), look for discussion between PleaseFixYourBugs and herb sutter, and between Charles and some guy who tried (and succeed) to wrap WRL in C++ constructs – both discussion have consensus that CX is simply unnecessary, doesn't bring anything new, doesn't make anything easier. It's purely there because MS wanted for this or the other reason.
GiovanniD: while I wouldn't throw as much hatred and bile at it as some others, I do think C++/CX is very misguided.
It's great that they give us a simpler, cleaner way to interop with WRT. The problem is that this "simpler, cleaner" way goes far beyond what is necessary to be an interop language. Despite what the official PR statements say, C++/CX is not *designed* to be used "at the boundary". It has been designed to creep in at all levels. It is designed for you to write your application in C++/CX, and not C++ with C++/CX at the edges.
Heck, even the people behind it have admitted as much when you pressed them a bit: yes, they *wanted* to create a language that you could use at the "boundary", but they didn't actually enforce this, and they didn't test it by writing their own applications in C++ with C++/CX at the edges. Their actual use cases, the example code they wrote and experimented with, was C++/CX throughout.
There are a number of simple changes that could have been done to make it a reasonable interop/boundary language. The most obvious is just giving C++/CX its own filetype extension. Make it clear to the compiler which language each file is (.cpp -> C++, and .cx (or something) -> C++/CX). But no, the didn't, which gives you no real way to *enforce* your "boundary" policy. Several of the extensions added are also completely unnecessary for the stated goal of being used for interoperability. (for example, partial classes serve no purpose in that context. But they were added because "well, our UI designers expect to have them, and we'd rather extend the language than redesign those".
And despite what you may think, "portability" is certainly an argument.
What if I write a cross-platform application which, among other things, should compile to WinRT? I certainly want as much of the code as possible to be as portable as possible then.
But there's also the flip side: what if I get tired of waiting for the MSVC team to bring their compiler up to date? They *promise* that VS2012 will be different, that *this time* we will get regular out-of-band updates with new features and everything. But what if I just wanted to compile an application with Clang, and target WinRT? Can you give me a reason why that should not be possible?
My problem with C++/CX is not what they *intended* it to be, and what they *claim* it is. My beef is with what it *actually* ended up being: yet another blob of proprietary nonstandard C++ extensions which are mashed into the C++ compiler without giving it any way to distinguish and keep them separate.
I'm already sick of VS2010's faux keyword treatment of words like "event" or "interface" or a number of others, and I'm not looking forward to adding to the pile of "things that might have had some special meaning if this code was to be considered Microsoft Proprietary C++ dialect of the week", and therefore cannot be handled correctly by the IDE, by Intellisense or by the compiler if I'm *not* using that dialect, if I'm just writing ISO C++.
The reason I and many others dislike C++/CX is because it demonstrates an incredible disregard and contempt for the language their compiler is named after. I don't mind language extensions, but I object to language extensions which don't even *try* to play nice, which don't respect that while they may have their uses in some situations, they're not *always* welcome, and (for some of the CX extensions, but not all) which were added when it wasn't strictly necessary.
@GiovanniD also if you read carefuly exchange between PleaseFixYourBugs and Jim Springfield, in one of his post Jim actually admits when put on the spot that:
a) Everything could be done with C++ while preserving maintainability of code and not having boilerplate code
b) THE ONLY reason that CX was concieved in favour of C++ was that they (MS) felt that it will be better received by their customers.
herb sutter somewhere as his only argument for CX could come up with was that it will be, how he put it: "Better looking in debugger", which of course pissed many people and he was basically booed down.
Now answer to yourself a question: Who do you think is the main customer (with regards to developers power) for a MS?
Pretty sure you're not meant to call it "Metro" any more…
I came into the comment section just to say I'm pleased to learn how c++/cx really works. I've read other comments complaining against c++/cx. I don't like c++/cx, but we have to use this "c# in c++" mix to create winrt apps. I think MS believes that c++ can only be used to create winrt components. The c++/cx compiler is designed for that. The Windows Team needed that to create winrt. I Hope this will change. But crossing an Abi boundary is not easy. Remember the win32 SendMessage method. Try this : write some code that populates a listbox in win32 (sendmessage) and winrt (^), and compare the codes. Not sure which one is nicer/better. Maybe we are missing some c++wrapper classes, à la MFC.
Okay, those of you who are upset that Microsoft went the C++/CX route, point taken. But the decision was made, and we're stuck with it, and some people are going to find C++/CX worthwhile and would like to learn how to use it and post comments asking questions about how to use it. That will be easier if the comments aren't filled up by people making the same point over and over again about how stupid an idea C++/CX is.
@Jesse: No, we have a whole team of people working on the Visual C++ libraries.
@Tom: I mean what I said: I had heard much about support for C++, and my first thought upon seeing the samples was that it was actually C++/CLI and that maybe there wasn't support for native code. I am thankful that there is support for native code :-)
@jon: The places it is used in this article are all the titles of other pages on MSDN. If those pages are renamed or moved, I'll come back and update the links.
@atch666, @grumpy: As you have noted, the pros and cons of the decision to develop C++/CX have already been discussed in some depth, in comments both here on this blog and in reply to a handful of Channel 9 videos on the subject. It is not my intent to reargue those points. Some people really like working with C++/CX; other people appear to think that the development of C++/CX is the worst thing to happen in the history of programming.
Visual C++ provides two options for building Windows Runtime components with C++: one is via the C++/CX language extensions, the other is via the WRL library and MIDL. If you want to build a Windows Runtime component, you can use either of them. I've done a fair amount of both, and I know there are tradeoffs to using each of them.
As explained in the article, the intent of this series of articles is to explain some of how C++/CX works and how C++/CX corresponds to C++ (sans-hats, using WRL), by walking through roughly equivalent code samples implemented using each. I'm interested in using this series of articles to discuss the technical aspects of C++/CX. I am not here to tell you that C++/CX is the greatest thing since sliced bread; I'm just here to discuss how it works.
@grumpy: A brief comment concerning your paragraph starting, "I'm already sick of VS2010's faux keyword treatment of words like 'event' or 'interface' or a number of others." In the IDE, Visual Studio 2012 offers a substantially better experience here with the new semantic colorization feature. For example, if you declare a class named 'event', it will be colored as a class, not a keyword. The same applies to other non-C++ keywords and contextual keywords. 'interface' is still problematic in a lot of code since the combaseapi.h header defines '#define interface struct'.
@Pierre Morel-Fourrier "I don't like c++/cx, but we have to use this" – Not according to James McNellis – Instead you can use WRL. Try and you'll see why WRL is not an option.
I'd encourage those of you interested in WRL (including those of you who are sure you already understand all that there is to know about it…) to watch this presentation by one of the designers of the library.
channel9.msdn.com/…/The-Windows-Runtime-Library-WRL-
Great start, James. Looking forward to the next installment!
C
would vc++ 2010 express get full support for c++ 11?
James McNellis: wow, so just to be clear w.r.t. "fake" keywords, are we just talking about IDE Coloring, or will Intellisense also work if you have such an identifier? (I really hope `interface` will behave better as well, at least in cases where it's not `#define`d to struct (if that define is in effect, there's obviously not much to do)
Anyway, that sounds nice. Glad to hear it has been improved.
@Mayuresh Kathe:
Answer most probably is *no*. (New version is out there – VS 2012)
@dissapointed_with_Very_Slow_and_Fake_C++ good news guys, embarcadero will ship later this year a XE3 which will have far superior C++ support to what Very Slow offers, and funny enough, we will be able to create our "Metropolis" UI style app using C++11 – no C++/Cx craap. How great is this?!
@atch666: Not. Because you don't need CX for Metro if you don't mind verbose COM code. So either you'll write COM code or use extensions regardless of IDE in use.
@Klimax writing code for Metro without CX is incredibly inefficient. I do mind verbose COM code, I think most people do. And what this "Not" of yours was about? Not what?
Guys, you will be much more tolerant to C++/CX when you see async/await constructs in it.
@atch666: "Not" was answer to your question. Since there is promise of no CX in other toolkit then it's clear it will use it's own extensions to hide COM verbosity. Or at best crazy set of macros and classes (maybe with help of ATL). (Maybe similar style as wxWidgets or QT…) Importing nice set of problems… (including problems with performance)
Also funilly enough AFAIK all C++ compilers have their own extensions to C++.
@tivadj2
What do you mean by async/await? From the name I assume this is something like task::then in PPL or futures in c++11?
@Klimax
The problem is you don't need "crazy set of macros and classes" to hide COM verbosity. Look at What Qt(not QT) does in e.g. QAxWidget class. You barely even know it's COM and everything is nicely hidden under the hood of a very slick library with just a handful of methods. No need for macros, exceptions, hresults or compiler extensions. Just plain old c++. And honestly I can't believe there are any performance benefits from c++/cx approach over a library approach.
@Krzysztof Kawa: Qt has own language extensions, isn't it?
@Alex no, Qt doesn't have it's language extension. I assume that you are referring to moc but this has nothing to do with language extension – you can write 100% ISO C++ in Qt. You are not forced to do anything else, by forced I mean if you don't chose "their" way you will suffer. Just like you suffer if you don't want to use Cx.
@tivadji intel's tbb does this and much more, much better, and interestingly – it's pure C++
@klimax if you study discussion between pleasefixyourbugs and james you'll see that everything can be done in iso c++ (what james himself confirms)
@atch666 there is no 'slots', 'Q_OBJECT', etc. keywords in ISO C++. So it is obviously a language extension. It doesn't matter if it is implemented as custom preprocessor or built-in into compiler. C++/CX also could be implemented in preprocessing stage but integrating it into compiler simplifies life a lot.
@Alex, the point is that Qt doesn't introduce new mutated syntax. You still CAN use multiple inheritance, regular pointers etc, YOU as a dev. are not forced while working in Qt to go out of ISO, you don't even have to use their so called "keywords" – they are simply macros and you don't want to tell me that defining a macro is creating language extension, do you?
On the other hand if you want to write Metro apps you more less FORCED to use CX. Try to not use it and then you'll see what I mean by being forced.
@atch666, what's the point of not using CX? The only thing I dislike in CX is that it is not supported in traditional desktop apps.
@Alex Being locked in, not being std conformant (hey those standards are made with many purposes), portability etc, etc.
It is like asking why on earth would I want to be standard conformant, why on bloody hell would I care and write my code according to good coding practices and so on and so on. It is as simple as that.
@Alex
> So it is obviously a language extension.
So you obviously have no idea what language extension is.
@atch666:
> portability
Metro apps are not portable to anything other than Windows 8 and Windows RT. So it makes no sense for WinRT to be portable.
@Alex
I see that you also don't (fully) understand what portability means. So there is still lot of learning for you (and for all of us for that matter) but the point is that argument like yours is just silly and naive. What if I wanted to port my application written using Very Slow (VS) to embarcadero XE3? Because that's also is a portability. This is the best example why STANDARDS and CONFORMANCE to thereof is very, very important. If at one point you as a very intelligent and creative dev decided that Very Slow is just weak and doesn't give you a chance to develop your apps the way you'd like it then, if (and only if) your app was written using std language then you can simply say to folks from MS (after few years of begging them first for new features which are implemented by other vendors for years now): Screeeeww youuuu! You didn't listen to me, I just cannot allow anymore to let you (MS)constrain me and my evolution as a developer, I am… and here is the interesting thing… PORTING my business elsewhere. You see? That way you're free, that way you have a choice.
But as the things are for now, by accepting Cx, If at one point you as a very intelligent and creative dev decided that Very Slow is just weak and doesn't give you a chance to develop your apps the way you'd like it then after years of begging MS for new features THEY will tell YOU (not in so many words of course): Screeeww youuu! We have locked you in our home brewed extension boy! You have no choice but stay with us! You are screeeewwed!
Do you see now, why portability and conformance to standards is so important? So you want allow to anybody to enslave you.
Regards
@Alex and change the "want" to "won't" from the last sentence of mine please.
@atch666
> embarcadero XE3
Do you know that C++ Builder forces you to use proprietary language extensions in every kind of GUI applications it supports? That it's standard libraries are written in Delphi? Even worse, it doesn't produce app packages that you could publish on Store. It tries to imitate Windows 8 look and feel with FireMonkey but build still produces exe files that you can run on older OS. And I would not be surprised if they doesn't integrate with Windows 8 features at all.
Your arguments are so childish. Do you argue with your employer/team lead that way when you are forced to use tools you don't like?
@Alex which of my arguments are childish? And as for a workplace – this is different story, you may be sure that many MS employees don't agree with MS's policies yet they won't say anything agains. Guess why. But please answer which arguments of mine are childish and why.
@Alex
Please watch more closely to what a language extension is. VCL and the likes are a library. That is a fundamental difference. I would love /CX to be implemented as a library and would have no objections whatsoever.
What Qt does is a pre-compile step supported by any build mechanism done by tools(moc and uic) that are opensource and can be built with the same compiler you use for your code. If you want to use them with gcc, intel, vc, clang or anything else you recompile them(takes seconds) and are good to go. Also if you don't want to use their keywords like slots and signals there are macro replacements: Q_SIGNAL, Q_SLOT – still vanilla C++ code. With C++/CX no such luck. Support for it would have to be added to the compiler itself, which in case of compilers like gcc simply won't happen for reasons I think are obvious.
On the subject of portability – it's not about running WInRT on say Linux(there's simply no point) but mainly being able to create Windows Store Apps with other compilers (mingw, intel etc.). With C++/CX in place this is effectively impossible (WRL is not an answer, it's just horrible).
Why would someone want to? For many reasons. Established workflow not using Visual Studio is first that comes to mind. Not having to pay for IDE or compiler is another.
Alex, we are not Microsoft's employees, we are their CUSTOMERS.
@atch666:
I know I can use C++ without CX, but then I have to work with COM or use libs hiding it. As far as CX goes it IS extension and no matter how much you try you cannot make it to be something else to suit your own argument and/or your agenda. (Or post proof as so far you had only assertions)
And its not like nobody else does language extensions… nor anybody forces you to use CX…
@Krzysztof Kawa
> On the subject of portability – it's not about running WInRT on say Linux(there's simply no point) but mainly being able to create Windows Store Apps with other compilers (mingw, intel etc.). With C++/CX in place this is effectively impossible (WRL is not an answer, it's just horrible).
It is worth recalling that in standard C++ it is also impossible as C++ doesn't have standartized ABI; different compilers have different STL implementations thus you cannot just return STL type from library compiled with one compiler and consume it in code built with different compiler or with different version of same compiler (similar limitations apply to exceptions). COM and C++/CX solve these problems.
Nobody stops you from writing wrapper library over WinRT interfaces for mingw if you need one. I don't think that caring about other compilers is something MS should do. And honestly I don't know why one would prefer mingw over msvc.
Intel compiler is source and binary compatible with msvc. CX support will probably come soon.
> Not having to pay for IDE or compiler is another.
There is Visual Studio 2012 Express for Windows 8 which is free for commercial use.
@Alex: different ABIs is a completely different issue. I am able to build a DLL with one compiler, and load it with another. Yes, there are limitations in terms of exceptions and non-POD types and STL types, but it's doable.
But with C++/CX you're just out of luck if you don't stick exactly to VS2012. You can't use VS2010, for example. Why not? Because "hey, it's been a long time since we invented our own proprietary language, I'm getting that itch again" Portability doesn't necessarily mean "runs on Linux". It doesn't necessarily mean "can build with GCC". It also means "Can build with the Microsoft compiler I happen to use today" Or "can build with the Microsoft compiler that's released next year". Or "can be understood by static analysis tools".
Even if I'm a good boy who chooses to use VS2012 to build my C++/CX code, even if I'm willing to sacrifice all the C++11 features and standards-conformance that other compilers offer, even then, I have other tools than just the compiler. I might want to run PVS Studio as my static analysis tool. I might want to run Doxygen over my source code. I might want to have syntax highlighting when viewing code in the web frontend for my source control tool. I might use Qt, which requires MOC to be able to parse the code. And so on, and so on.
> I don't think that caring about other compilers is something MS should do.
No. But caring about their customers is something they should do.
> Intel compiler is source and binary compatible with msvc. CX support will probably come soon.
"Probably". See, that's the question. Will it? Is C++/CX so well-specified that it is **possible** for other compilers to implement it? Has Microsoft committed to such a specification? Will they follow the specification if bugs in their own implementation deviates from it?
If you're right, if it is *possible* for other compilers to implement C++/CX support, then yes, a lot of these complaints will fall away. But I see little evidence for it. When Microsoft came up with AMP, they clearly announced that "we're writing a formal specification so that anyone can implement it. We *want* third parties to implement this". With C++/CX? Not so much.
@Alex
>It is worth recalling that in standard C++ it is also impossible as C++ doesn't have standartized ABI
So your point is that inventing unportable closed-source extensions is better than pushing for standardization for anyone (including MS itself and its customers)? I strongly disagree.
>Nobody stops you from writing wrapper library over WinRT interfaces for mingw if you need one. I don't think that caring about other compilers is something MS should do. And honestly I don't know why one would prefer mingw over msvc.
MS stops me. I can't write a wrapper without using their compiler, which, as you pointed out yourself – might not be binary compatible with the rest of my project (if not written very carefully). While msvc is generally better compiler for windows in terms of performance or file size it's light years behind when it comes to c++11 implementation completeness and even further behind say clang in terms of debug information and static analysis. So it's a question of your needs at any particular time – binary optimisation or developer effectiveness and productivity or a decent output when you're debugging say complex templates.
> Intel compiler is source and binary compatible with msvc. CX support will probably come soon.
"probably" is the key here. I really have my doubts on this one. They tried this once with c++/cli and up to now only the mono project picked it up and it's hardly a widespread or popular solution.
Btw. I never used icc myself, but wikipedia says: "(…) Since then, the compiler has been and remains compatible with GCC 3.2 and later." so I'm confused about what you said about compatibility with msvc? Do you know anything more about this?
> There is Visual Studio 2012 Express for Windows 8 which is free for commercial use.
Express is a no-go in any larger project. Main reason is that it doesn't support plugins so using any tools like Qt add-in or VisualAssistX or integrating with source control systems, custom build flow or bug-trackers is very hard or plain impossible compared to other freeware IDEs.
@grumpy summed up my primary issue with C++/CX, which is that it was introduced in a way that makes it very difficult to keep it contained in a "boundary layer" the way Sutter and other have recommended. Co-opting the ".cpp" file extension is the most egregious example of this. My suggestion for MS would be to designate a different extension for C++/CX (".cx" or ".ccx", perhaps), and then to add a compiler option so that the /CX extensions can be rejected in other files.
I'm back from an Embarcadero XE3 presentation. It doesn't do Metro: Metropolis UI is a Metro-like UI running as a desktop app (like the Zune app). Good about that? It could be deployed in Win XP (if we needed a touch-first UI in XP at all). Bad: it's still a desktop app, forget about selling it through the Store. There's no Express edition, either. Overall impression: mediocre. Disclaimer: I'm an independent developer.
@Diegum
>It doesn't do Metro: Metropolis UI is a Metro-like UI running as a desktop app
First, I can see only positives. What's wrong or what's worse in having desktop app to a Metro app? With desktop you have full power of desktop, with metro as you probably well know you are constrained in so many ways.
Second, What do you mean it doesn't do Metro? What's Metro? AFAIC Metro is a new user interface (widely understood). If so, it is like saying, only microsoft can produce cars, others at best can produce automobiles.
Thirdly, mediocre? fair enough, never claimed that they are fantastic, but isn't Very Slow mediocre too?
Fourthly, the point of not being able to put it into MS store? For decades people were selling their apps without MS store, I believe that they simply don't need it. If your app is good you will sell it without MS store. If your app is bad nothing will help you, not even MS store.
The point is that with XE3 you can have Metropolis application without being constrained in so many ways by Very Slow and CX and as you are probably aware they are going to use fantastic clang compiler which it's on its own selling point to me.
Regards
@jalf: It looks like other Intellisense features (e.g., Go to Definition) do not work with identifiers like "interface." I'll talk with our IDE team to see whether that's a known issue and will open a bug if required.
@atch666: A comment in reply to your comment from 5 Sep 2012 1:07 AM: Windows Runtime does not support multiple inheritance (and hierarchies of public types are only permitted in a small set of scenarios); this is a restriction imposed by the runtime (and, in a sense, the metadata format), not one imposed by the C++/CX language extensions. A T^ may be reinterpreted as a T*, which makes interoperation of hats and ComPtr smart pointers fairly straightforward.
@Krzysztof Kawa: I'm curious about your statement that "WRL is not an answer, it's just horrible." Are there particular features (or lack-of-features) that you dislike? Do you have any suggestions on what would make it more usable? (I've written quite a bit of code that uses WRL–more than I've written using C++/CX–and while the code is often fairly verbose, I've found it to be quite usable. I'm curious what problems you've run into in using it. Feel free to drop me an e-mail if you'd prefer: james.mcnellis@microsoft.com.)
@S. Colcord: There is a compiler option: a translation unit that makes use of C++/CX must be compiled with /ZW. If you attempt to compile a C++/CX program without that option, the compiler will balk at the C++/CX extensions. You can name your source files with any extension you'd like (and use the /TC option to notify the compiler that it's a source file).
I'm curious about why you think this makes it harder to use C++/CX solely at the boundary: I would have assumed that it would be more confusing if a different file extension was used by default. A C++/CX translation unit can make use of any C++ code. Currently, the .cpp extension already doesn't say much about the source code: much C++ code already relies on nonstandard extensions (or, perhaps more commonly, mostly-standard C++ code often relies on quirks or bugs in a particular set of compilers that have been used to test it).
If one wants absolute separation between code written in standard C++ and code written using C++/CX, I would recommend building the standard C++ code as a library and linking it with the C++/CX component: this allows verification that the library can be built without C++/CX support. (Actually, I'd recommend doing this regardless–it makes code easier to test and verify, and code portability is A Good Thing.)
@atch666: In reply to your last comment, on 6 Sep 2012 10:58 PM: @Diegum states that "it's still a desktop app," so "it doesn't do Metro" means that it doesn't produce a Windows Store app and thus it doesn't run in the new Windows 8 UI environment.
[I've been on vacation for the last week, hence my delayed replies.]
@James thank you for your reply.
>new Windows 8 UI environment
Correct me if I'm wrong, but there isn't such thing as windows 8 ui environment only Windows 8 environment, right? What do you mean when you say that app produced in XE3 doesn't run in Windows 8 UI environement? That it doesn't have Windows UI look&feel? You're wrong because it does have. Do you mean that it cannot be run in windows 8 OS? You're wrong because it can precisely do it. So what you seem to imply is that the only constraint on it, will be that it will not be able to be available through Win8 app store? As I've already said, if someone's app is good no win app store is needed to sell it. If on the other hand someone produced craappy app, win app store will be of no help to him. Ok, that's dealt with. Now your argument with Colcord et al. James I suspect that you are intelligent person and I cannot possibly imagine that you really cannot see their points, and also cannot possibly imagine that you actually believe in the argument you've presented. If on the other hands you need any suggestions, as you ask K.Kawa, go to link I've provided and watch discussion between PleaseFixYourBugs and Jim Springfield. blogs.msdn.com/…/10228473.aspx
Regards
@James
> Windows Runtime does not support multiple inheritance (and hierarchies of public types are only permitted in a small set of scenarios); this is a restriction imposed by the runtime (and, in a sense, the metadata format), not one imposed by the C++/CX language extensions
James, I don't care "what" does not allow me to use multiple inheritance, be it run time, be it CX, be it some other thing. The point what matters is that I cannot use multiple inheritance. Second point is, that I am not even convinced (I have no expertise in this area) that Windows Runtime doesn't support multiple inheritance. If those Metro apps can be made out of Cx (at the boundary only) and C++ at it's core, so if I follow that Metro app is running on Windows Runtime and is made out of CX and C++ this means that Windows Runtime supports multiple inheritance when C++ is concerned. If so, then what you're saying is incorrect. Windows runtime supports multiple inheritance, it just doesn't do it (laugh) when Cx is concerned.
Another argument: ok, as you said yourself, we (developers) do not have to use Cx at all to write metro apps, right? Right, ok, then we can write our apps in WRL which is horrible but this is different story. If, we can write our metro apps in WRL and we use multiple inheritance in our apps (because we are not constrained by Cx) and we can run it as metro apps, then it follows that Windows runtime support multiple inheritance, it is just Cx doesn't support it. As simple as that.
Having said that, let's forget those silly Metro apps or whatever you are now told to call them. What about desktop apps? If they can be run on Windows 8, and they are written using C++, then it follows that Windows runtime supports multiple inheritance, why wouldn't it? Cx doesn't support inheritance, and that the whole point.
Regards
@atch666: Windows Store apps are the new class of apps, built using the Windows Runtime, designed for Windows 8. They are fundamentally different from ordinary desktop apps. If you've used Windows 8, it's pretty obvious which apps are Windows Store apps (formerly called "Metro style apps") and which are desktop ("classic") apps.
Unlike desktop apps, these apps can only be distributed via the Windows Store (there's an exception to this rule that applies in enterprise environments). I am not an expert on building apps, and I am not familiar with the Windows Store rules; for more information on those subjects, I'd recommend the many posts on the Windows 8 app developer blog (blogs.msdn.com/…/windowsappdev) and the MSDN documentation for Windows Store apps (msdn.microsoft.com/…/apps).
I'm not sure what leads you to think that my last comment was insincere. I understand that people have concerns, and I'd like to help find ways to mitigate those concerns. I've spent quite a bit of time writing Windows Runtime components over the last year, using both C++/CX and WRL, and have not had much difficulty using C++/CX (or WRL) only on the boundary, which is the recommendation that we've made ever since C++/CX was announced last year.
As has been explained–both in this thread of comments and in threads elsewhere on this blog, on MSDN Forums, and in Channel 9 discussion–you don't have to use C++/CX if you don't want to. You are free to write your code however you like. C++/CX is just one option, and I think that many people are going to find it a compelling tool when writing native Windows Runtime components and Windows Store apps.
In reply to your second comment: one must distinguish between Windows Runtime types (types that can be used across the Windows Runtime ABI boundary) and arbitrary C++ types. Some features of the C++ type system (like multiple inheritance) have no equivalent in the Windows Runtime type system. C++/CX is not designed for building general C++ code, it's designed for creating and using Windows Runtime components, which are necessarily constrained by the rules of the Windows Runtime type system.
You have said several times in this thread that WRL is "horrible." Have you used it for building Windows Runtime components? Do you have any specific feedback concerning which features of WRL you consider horrible, or suggestions for improvement?
@James
Well, on several occasions MS guys hinted that WRL is a bit more verbose than C++/CX. The problem I have with this is that it's not a bit more verbose. It's massively, horribly over-verbose.
I admit that I don't have that much experience with it, but I followed several presentations and examples, than tried to write few components myself. The amount of code I got to achieve simple things, like a class with just a handful of methods.. this is the horrible part for me. I just honestly can't imagine using it for anything more than short examples without making it unmaintainable. I showed an example to my friend(also a professional C++ programmer for some years now) and he couldn't believe the amount of machinery used to make a method that returns 42.
I know I sound negative about this but it's not without a cause. Few times now I've mentioned Qt library on this board. That's because I use it in my work and private projects every day and I absolutely love its simplicity. Complex tasks like networking, threading, graphics, COM etc. can be grasped with just a few lines of very simple, readable code. I can't even think how much WRL code I would have to write to achieve the same goals Qt one-liners solve for me.
To back up my words – take a look at the example in "C++/CX Part 1 of [n]" post – 109(I removed empty lines and comments!!!) lines of code in 4 files (3 .cpp and an .idl) to get a component with getter/setter for an int??? Not to mention the "override" extension keyword that got its way there. Come on… there HAS GOT TO BE a better way to write a library… thank god for "auto" at least…
This all is not cause I'm lazy and don't like to write code :) I just believe WRL could have been much much cleaner and leaner and I just value my time too much to deal with it in this present form.
As for the features I'd like for WRL…
This is the C++/CX code from the part 1 example:
namespace CxxCXNumberComponent
{
public ref class Number sealed
{
public:
Number() : _value(0) { }
int GetValue() { return _value; }
void SetValue(int value) { _value = value; }
private:
int _value;
};
}
I'd like WRL to look as closely as possible to this:
namespace CxxWRLNumberComponent
{
class Number : public WRLClass
{
public:
Number(): _value(0) { }
int GetValue() { return _value; }
void SetValue(int value) { _value = value; }
private:
int _value;
};
}
I understand it can't be THAT simple cause of COM and metadata so throw an iso c++ conformant macro in there if you will or even a #pragma if you can't help it but don't make it 109 lines in 4 files long!
@James thank you for your reply.
To answer your question, yes, I did try to use it and also I did try to do same task with cx. Guess what? WRL is horrible. Even look at the examples you've provided and how much more and unreadable/unmaintainable stuff there is compared to Cx!
The truth is that Cx was designed to suit .Net crowd (even comments from Ms suggest this) and we, C++ devs are left with if you please "second class" alternative. Oh yes, we can just not use Cx, but then we have to go through hell in order to achieve what is quite easily achievable with Cx. And that's the whole point. There was absolutely NO NECESSITY (Jim Springfield confirms) to go with Cx – C++ could be as easily (or easier) used. The problem is that MS had milions of devs enticed with C# and .NET and they (MS) just couldn't abandon them, so they've created .NET-ish language. As simple as this. Nobody thought about C++ devs for more than 5 minutes. That's why I concur with Knowing me, knowing you, a-ha, and agree that herb sutter is a traitor to C++.
@Krzysztof Kawa: Thanks for your feedback. Yes, WRL code is more verbose than equivalent C++/CX code, and it's much more tedious to write and more difficult to write correctly. It's more flexible and offers much more control over practically everything, but that flexibility comes at a cost of higher complexity.
To address two specific points that you made: first, 'override' is not an extension, it's a feature of C++11. It's optional in standard C++ code, but it is very useful and I'd recommend using it if possible. Second, with respect to the 109 lines of code in the WRL component from Part 1: to be fair, about 40% of that code is in the module.cpp file, which is all boilerplate and is per-module, not per-type (actually, I copied that code directly from the WRL project template). This code looks worse (i.e. more verbose) than it really is because the project itself is so small: in a larger project, the relative size of that code would be insignificant.
The remaining code (the IDL and C++ definitions of the Number type and its interface) is still verbose, absolutely, but everything that is there is required. Any other library or set of compiler extensions would somehow need to be able to generate that code somehow: via language extensions like C++/CX, by using macros to generate the boilerplate, or perhaps through some sort of preprocessing step (that's not an exhaustive list of options–just some examples).
The closer you want to get to your "target" code (so far as I can tell, it's just ordinary C++ code), the more work you need the compiler (or some sort of preprocessor) to do for you. There's only so much that a library can do. WRL encapsulates a lot of the boilerplate code, but to be able to build or consume Windows Runtime types using clean, simple code that is easy to write correctly, language extensions like C++/CX are a preferable solution. Future posts in this series will cover additional transformations that are done and why compiler support is required.
@atch666: Ad hominem attacks do not in any way help your argument and are not welcome here. If you'd like to make such comments, I would request that you find some other venue.
@James
> first, 'override' is not an extension, it's a feature of C++11.
Ah, my bad. There's so much new things in C++11 it's hard to remember everything :)
> to be fair, about 40% of that code is in the module.cpp file
Yup, true again. But why don't I see it in the /cx version then? If /cx can hide it from me why can't WRL do it too? The answer is – it could. But instead it just has this "naaah, just use our proprietary /cx extension" feeling all over the place.
> The remaining code (the IDL and C++ definitions of the Number type and its interface) is still verbose, absolutely, but everything that is there is required.
Yes, this is understandable.
> Any other library or set of compiler extensions would somehow need to be able to generate that code somehow
Yes, so why is it left to programmer to do it manually unlike with /cx? I see no uuids or [activatable] thingies in /cx code and yet the underlying machinery is still generated automagically and correctly by the compiler. This could be done perfectly well within a library with plain c++ or, in worst case, with some "not-that-ugly" macros.
> There's only so much that a library can do.
Take a look at boost or (again) Qt. Or even the stl! If we can have threads as a library I honestly don't see a problem with a little reflection or COM. There is very very much that a well written library can do and efficiently at that.
> WRL encapsulates a lot of the boilerplate code, but to be able to build or consume Windows Runtime types using clean, simple code that is easy to write correctly, language extensions like C++/CX are a preferable solution.
Not preferred by me and, judging by the comments on this board, not by many others too. Certainly not by people who for any reason would like to use another compiler and at the same time target new windows runtime.
You guys always say you listen to us but somehow you don't seem to hear. You talk about c++ renaissance and than pull a /cx on us. This creation of new c++ish languages and yet another compiler extensions with each new VS version has to stop at some point. It's madness (not to sound too Spartish). But yeah, this argument was raised way too many times already so I'll just leave it at that.
> Future posts in this series will cover additional transformations that are done and why compiler support is required.
I'm honestly looking forward to that and wish for the best. I would love to think to myself at some point: "yup, this is the right way to do it", but so far this just seems like another c++/cli (compiled to native code this time) misunderstanding and I fear it will end up the same – as something replaced by c++/whatever in VC.next. I know c++/cli is not technically removed yet, but lets be honest – it was a bad idea, dying the slow death it deserves.
@atch666
To be honest the thing that XE3 does seems to me just plain bad too and I can't see it catching on. It's like when people installed all kind of crap on Windows XP to make it look and behave like Windows 7 when it came out. To some extent it worked, but not always, not that well and caused more problems than it solved. Pointless. Desktop apps (what XE3 does) don't follow the same life-cycle, power and memory management rules, task switching patterns etc. etc. The look and feel can be simulated to some extent but it's just not the real deal and never will be.
@James I'm not attacking anobody, let's be honest, the only thing I've said is that I agree with someone's opinion and this surely cannot be seen as an attack. I'm here not to cause disturbance of any kind. Argue? Yes, I argue, but I believe that I am right in what I'm saying and judging by other's comments I see that lots of people feel exactly the same.
@Kawa my main point with XE3 was that so called Metro apps CAN be made using C++ only. Another story is if this will take off or not. But the point is still valid – no Cx is required, no complicated, unmaintainable code is required to do Metro.
@atch666 You called Herb Sutter a traitor to C++. I don't know how you can say that's not attacking someone. That was really uncalled for.
@GregM Cx was the cause that he was first called a traitor. So I disagree that it was uncalled for. The call was made as soon as last year's presentation of //build was over and every folks saw what MS meant by C++ Renaissance, which herb sutter was so enthusiastic about. That's why I said that I agree with Knowing me, knowing you, a-ha.
@atch666: People don't insult others just because their opinion is different. Grow up.
@atch666 The fact that other people did it first doesn't change the fact that you were attacking him and it was uncalled for. Stay away from personal attacks and people will be more likely to accept your arguments.
@cppguy what do you mean their opinions differ? AFAIC before //build nobody including herb sutter let us know that C++ renaisance doesn't really mean C++ renaisance. Everyone including him, behaved as if C++ will be the language they've chosen. Everyone including herb sutter were talking how great C++ is, its advantages, etc, etc, how he loves C++, etc, etc. As it turned out, virtually nothing has been done with C++11 status. Moreover, herb sutter after //build tried to convince people that Cx is the way to go and that everyone should use it – this ended up with him being virtually told to go away and stop talking nonsense. Also, the poor alternative provided in the form of WRL only confirms the fact that C++ isn't first class citizen in MS and never was considered as such, despite the talks what were given before //build. What those facts tell about behaviour of herb sutter? Before //build: C++ is great, we love it, now it's C++ time etc etc.
After //build: Cx is the best option, use it, it looks great, etc etc.
All I'm saying is that such a behaviour can be seen as having traits of "sitting on a fence". This in turn (sitting on the fence) is very often one of main characteristics of traitors.
They go where the best (whatever is best for them) is offered to them, and they have loyalty for nothing. In this case loyalty to C++ community.
That's why I agree with the point of view of Knowing me, knowing you, a-ha.
@GregM Look, I have right to agree with someone's opinion even though this opinion may be hurtful to some other person. The point is that I believe and feel that Knowing me,….'s attitude and response however overheated it was nonetheless it was correct and justified response. How would you feel if for months someone tells you/promisses you that now is the time, now it's c++, now we are in full love with C++, now our IDE will be fully supporting c++ because this is the language of the future etc, etc, ok? so for many months you hear those promisses and suddenly, one //build and not only you realize that nothing what has been told is in fact true but the person (herb sutter) who was telling all those stories, now suddenly, he changed the side of the fence and wants to convince you that in fact C++ isn't the best, that due to it's shortcomings they had to go with Cx, that Cx is the way to go, that this is better for everyone, etc, etc.
How would you feel if someone treat you that way? What would you think about this person?
That's why I repeat: I agree with Knowing me, knowing you, a-ha and I also believe that herb sutter by his behaviour before and after //build presented characteristics which can be only associated with traitors.
@atch666 You could very easily express that opinion without resorting to personal attacks like calling him a traitor. Your points may be perfectly valid, but if you keep on with the personal attacks, you're just going to end up being ignored. If that's what you want, fine, but that's not going to help you get your issue resolved.
@GregM and do you really believe that you will not be ignored by MS? Think about it Greg.
In any case, I'm not going to go around giving them more excuses to do it, plus there's really no justification for personal attacks. If you can't see that, then there's obviously nothing more to say on that topic.
Thanks for this, can you fix the second URL to point to right place from http://blogs.msdn.com/b/vcblog/archive/2012/09/05/cxxcxpart01asimpleclass.aspx
to
https://blogs.msdn.microsoft.com/vcblog/2012/09/05/ccx-part-1-of-n-a-simple-class/