Main omissions I've noticed: printf isn't quite the same (no 'z' modifier, the 'n' forms are noticeably inferior), no VLAs.Also, standard library isn't POSIX (which is not an omission but a lot of C code assumes POSIX so you'll probably end up having to deal with this).
I'm surprised you mention intrinsics, since VC++ has a wide selection - https://msdn.microsoft.com/en-us/library/hh977022.aspx - and I'd expect, though without proof, the differences between many of those available on both VC++ and gcc/clang to be something you could work around with #define or, failing that, a small inline function (and cross your fingers).
Aside from VLAs, which is annoying, you can work around most of these with wrapper functions and #defines. So I've been pleased enough with the latest VC++. As a long time programmer for multiple platforms, I can put up with a certain amount of deprivation, and having to put in a bit of effort doesn't bother me (all that much). But I've noticed a tendency for people to sometimes assume that "multiple platforms" means "ten different types of gcc+POSIX+fork+pthreads". I'm sure that even shiny new C99-friendly VC++ won't make them happy.
This. Unfortunate, but some even seem to think C99 support automatically means POSIX and then start complaining a platform isn't compatible if it doesn't handle what they thought was portable code..
Also interesting to contrast your description of PS3 with Naughty Dog comments. Seems like they got a lot more out of them but had to work hard to do it. Curious, there were products that auto-synthesized code for SPU's like RapidMind. I had planned on trying them had I used PS3's for acceleration. Did you or anyone in that industry try those tools to see if they delivered similar performance over hand-coded algorithms in gaming workloads?
http://www.theregister.co.uk/Print/2007/05/08/rapidmind_two/
Meanwhile, my team was multiplatform. That meant most people could hide in the easy spaces on the PC or maybe the 360. We had a small group of Russians and Europeans who enjoyed the challenge of hand-optimizing the SPU. They would not have tolerated synthesized code ;)
I'd probably try to get more in OSS projects but they can be a rowdy bunch. Gotta have manager or leader that can keep the egos and nationalism in check. ;)
and 32/64bit..
UNIX was seen as the C runtime. When the standard came ANSI C adopted what was considered the minimum portable bits one could use in non UNIX systems.
Then came POSIX, which isn't as portable as many think. It also enjoys some of the UB and implementation specific behavior of the C world.
C++ while trying to cater to C developers adopted the same attitude.
Thankfully the C++ committee is changing that with C++17.
http://blog.llvm.org/2011/05/what-every-c-programmer-should-...
http://blog.llvm.org/2011/05/what-every-c-programmer-should-...
http://blog.llvm.org/2011/05/what-every-c-programmer-should-...
Many equate "C == what my compiler does", but just like any standardized technology with holes open to implementers to decide upon, portability isn't as people think.
Implementing an effective compiler is another concern entirely, but I would still argue that there tend to be more incompatibilities between C++ implementations than C.
However many C++ incompatibilities are actually caused by C compatibility and the goal of having higher constructs that are copy paste compatible with C but with additional semantics, e.g. structs.
So in both cases, to achieve your portability goal the languages would have to be fully specified.
As a C/C++ user, I'm honestly still not sure why a number of C features have yet to be formalized in C++ (e.g. restrict).
Which C++17 feature are you referring to? Modules?
Filesystems, networking, concurrency, ....
Sadly databases died out apparently.
Some of the issues C++ had were:
- C compilers were still catching up with ANSI C89 and it was a mess
- C++ being in the process of becoming standardise was even worse. It was quite hard to find out what were the working common features between compiler vendors, specially in terms of semantics
- The C culture that prevented many nice frameworks to succeed, because they were too high level, hence why MFC is such a thin wrapper over Win32.
- Lack of standard ABI in an age people only shared binary libraries.
C++14 and C++17 look really nice, but I doubt C++ will recover its place at the enterprise, beyond performance critical libraries/modules.
The reality is, without it, developing software for a platform takes more effort which I think is one of the reasons languages have taken on the initiative of building portable interfaces. Even C11 has added threads.h.
Having done multiple platform C development across Aix, HP-UX, Solaris, GNU/Linux and Windows in the first .com wave, as well as, having some embedded knowledge, it is always interesting that for some people only gcc and now clang exist.
As for C99, Microsoft is pretty clear that are only supporting what is required by the C++ standard.
Here's an older article - http://blogs.msdn.com/b/vcblog/archive/2013/07/19/c99-librar...
(I've seen more recent ones, but I can't find an example to hand)
http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17...
"Q. What about the C99 Core Language, or the C11 Core Language and Standard Library?
A. Our top priority is C++ conformance. We've implemented the C99 Standard Library because C++11 incorporated it by reference. C++ (up to the current Working Paper) hasn't incorporated the C99 Core Language in its entirety (only a handful of features, listed above), nor is it ever likely to. It may incorporate the C11 Standard Library at some point in the future, but that hasn't happened yet.
In VS 2013, the compiler team implemented some C99 Core Language features in C mode (e.g. designated initializers, see MSDN for the full list), in order to support some popular libraries. "
There was a C9 interview about it, need to search for it.
https://channel9.msdn.com/Events/Visual-Studio/Launch-2013/V...
Starting at 00:18:40, note the "not an intent to conform to C99/C11".
FFMpeg was one of the customers
If I recall correctly it was at a Visual Studio event last year, on those floor interviews they publish with the teams on C9.
https://helpx.adobe.com/creative-suite/kb/microsoft-visual-c...
There's probably quite a few internal-only users of Visual C++ too.
EDIT: Well, they're a high-profile user of Visual C++, I have no idea if they require C99 support but they ship a Mac version so it's possible.
This was the only time period I used C instead of C++ at work.
However I do confess, the situation for C++ support was even worse, so although I am not fan of C, the decision made sense from business point of view.
What we did was, we used the vendor compilers to compile gcc for a platform (or maybe used gcc to cross-compile itself, I forget). Then we used that gcc to compile gcc for that platform. Then we used the new gcc to compile gcc for that platform, and made sure that it was the same as the previous gcc. This wasn't easy - we had one guy that this is pretty much all he did for months. But it got us to a place where we were free from the vendor compilers.
It was back in the first .com wave, so 1999 - 2002.
> Was gcc an option at that time? Or did management require you to use the vendor compiler?
Customers did. Our software needed to integrate with their existing toolchains.
At least for our customers gcc was not a serious compiler, given the license and being that funny open source thingy.
Turbo Pascal -> C (meh) -> C++ (great back in business!)
Even though I mostly do JVM and .NET nowadays, still enjoy playing with C++ on the side, specially for mobile OS coding.
I see dropping C support on Windows as a means to force developers to migrate to more secure languages, but of course Microsoft should do what makes business sense.
Since VS2013 there has been partial C99 support and as such this is not needed anymore, finally.
Forgive me as I might be wrong but aren't system intrinsics the same in each compiler? I was under this impression as I wrote a lot of SSE2/3 C99 code for the GCC using MSVC++ documentation it compiles/runs without an issue. (This also before finding the MMX/SSE/AVX docs that intel has which are beautiful).
I mean the function/variable type names (for x86_64 at least) are the same for Clang/ICC/GCC/MSVC.
>> I mean the function/variable type names (for x86_64 at least) are the same for Clang/ICC/GCC/MSVC.
Yes, all those compilers support the same names for x86_64. Then a different set for ARM NEON, and a different set for PPC AltiVec. What GCC has done is implement another set of names that can be used across all those hardware architectures. To clarify the difference, you can choose - do you want to move your code between different compilers, or different hardware but always with GCC.
I actually find this style clearer since all the variables are accounted for at the beginning and it helps when looking for them (and associated comments, if any). You can always open a new block when you need a new set of variables. Do you happen to have started with a more dynamic language which didn't require variables to be declared? That was the case I've seen with most other programmers who preferred creating (often very many) variables only at the point of use.
I find the style easier to read as you can instantly see what variables will be operated on, what arrays filled etc. It's also quite important for me to know how much stuff is allocated in given block so I don't blow out the stack and having all the things at the top makes it easier to think about. It's probably about being used to it but I found the code with mixed declarations and logic to be inelegant and more difficult to understand.
You're exposing your code to unnecessary bugs where you user the variable prematurely.
Variables tend to be declared further from their use, making it harder to find them and see their types.
The stack size argument is wrong, because variables aren't necessarily on the stack, and non variable allocations may be put on the stack (i.e it's neither necessary nor sufficient to predict stack use).
You're discouraged from creating intermediate variables that aid readability.
You're discouraged from declaring your variables const, losing extra safety.
All in all, it's a terrible way to code.
As I said I like it because I like seeing what will be operated on when I start reading a block. I don't need to initialize them just yet.
>>You're exposing your code to unnecessary bugs where you user the variable prematurely.
The compiler warns when you use uninitialized variable. Just don't initialize them to random things, leave them uninitialized.
>>Variables tend to be declared further from their use, making it harder to find them and see their types.
I mean, I can see how that could be a problem but I don't have blocks bigger than one screen so I can alway see them anyway. I like short functions/blocks. It's also way easier to visualize what is happening if I allocate memory in my brain for the variables so to speak.
>>The stack size argument is wrong, because variables aren't necessarily on the stack, and non variable allocations may be put on the stack (i.e it's neither necessary nor sufficient to predict stack use).
It might be technically wrong but the real problems are arrays as they are the only thing which could blow out the stack (especially in recursive functions) so yeah, I don't see it as a problem although I imagine it could be for some.
>>You're discouraged from creating intermediate variables that aid readability.
I am not discouraged. Again, maybe it sounds super strange to you but I am actually discouraged if I had to put them in the middle of the code logic as I find it ugly and I need to readjust my picture of what is going on once I encounter some new variable I didn't know is going to be there when glancing at the block.
>>You're discouraged from declaring your variables const, losing extra safety.
I think const is as good as useless in C when it comes to declaring variables. I don't think it gives any extra safety it's just more typing and additional pain.
>>All in all, it's a terrible way to code.
I don't know. I think you lost the perspective. One way or the other it won't be a big difference and a lot of good code is written in the old/traditional style. You may think it's worse but it is not terrible.
With modern compiler backends you haven't been able to reliably reason about stack usage by looking at the number of local variables for quite some time. Even ignoring IR-level optimizations and register allocation, modern compilers will do coloring on the stack slots that remain, meaning that the number of stack locations you end up using is flow-sensitive (and thus moving to the top is actually technically obscuring things).
Beginning of block variables are generally always worse than as late as possible variables.
The article isn't very clear, but I would guess backward compatibility is going to trump adding new features as far as the C compiler goes.
I wouldn't mind getting proved wrong, but the article mentions a lot of C++ features they're working on, and doesn't mention an C features they're working on.
Microsoft keeps surprising me lately!
I'd also like to have compatibility of some language extension features, such as built-in functions and attributes. In particular, CPU-agnostic intrinsics for common instructions like atomics, popcount or count leading zeros as well SIMD arithmetic would be great.
My favorite C language extension is SIMD vector arithmetic with infix operators. You can get really pretty and portable (!) vector math code written in Clang and GCC using vector extensions, but again, it's not available in MSVC.
For most of my current projects, I have no intent of supporting the (current) Microsoft C compiler. It's not worth the effort.