Hacker News new | past | comments | ask | show | jobs | submit login

A more accurate title would be "The Sorry State of Microsoft's C++ Compiler".

As usual with native code, portability is actually quite easy to achieve - except to Windows using MS's native tools.




Oh come now, porting things to Windows is about as tricky as porting things to any platform that isn't completely insane or bizarre. Windows has its fair share of oddities, maybe more, but overall it's very similar to most other commonly available operating systems. If you're writing a program that runs in user mode, like a game, the porting is easy if you make it easy, and hard if you make it hard. So, do try not to make it hard.

You can't just sort of tack portability on at the end, by targeting one system and then trying to build on the other one(s) right at the end. That's just going to involve a pile of work, that you could avoid. If you build on all of the systems you target, all the time, and fix problems as they arise, it's much easier.

There was (and maybe still is) this notion that portability for Windows programmers consisted of "Windows '95 AND Windows NT". There might be a newer version of the saying these days, probably "Windows 7 32-bit AND 64-bit". But anyway, it was rightly used as a stick to beat Windows programmers with. But the competing approach, of sticking to gcc, maybe using POSIX and pthreads, perhaps relying on fork a lot, etc., etc., and then crying foul when it won't work on Windows... well, that's always seemed to be perfectly acceptable for some reason ;)


My experience: When implementing ZeroMQ, porting it to a new platform normally took few hours. Porting it to OpenVMS, which is a real oddball among modern operating systems took several days. Porting it to Windows took several months. Even today, after years of active development there are still features that don't work on Windows.


Well, I'm more confident about video games than I am about ZeroMQ, I have to say. But I might imagine on balance of probabilities that this will turn out to be a case of "POSIX and pthreads" ;) - it often is with Unix stuff. (Sadly, Windows ain't POSIX, and it doesn't have pthreads. So... there you go.)

But it's certainly possible that Windows is even more bizarre than I suppose, in ways that I have yet to encounter.


Would be much more useful to say why it took that long...


Was it because epoll vs iocp differences?


Now that's one area where Windows really differs. You can't write a high performance server for Windows without using IOCP, which couldn't be more different from what every other platform has for that kind of thing (epoll, kqueue, /dev/poll, ...)

It was interesting watching node/libuv face all the same problems I did when originally trying to abstract over this.


It is possible to wrap iocp api into a bsd-style socket interface compatible with epoll semantics. It ain't pretty, the socket int becomes an index into an internal map of per-socket support structs, there are ungodly edge cases and what not, but it's doable nonetheless.


Solaris?


Interesting - I wasn't aware that any other platform implemented IOCP. I wonder how that performs vs. traditional I/O with /dev/poll?



epoll/iocp is the most visible difference, however, the amount of time spent porting is more due to subtle differences in every POSIX-like function. File discriptor is int? Nope, it's SOCKET. -1 means it is invalid? Nope. Use INVALID_SOCKET instead. error codes are stored in errno? No. Use WSAGetLastError() to retrieve the error. Still, EAGAIN should be EAGAIN, even on Windows? No. Use WSAEAGAIN instead. And so on and on.


Doesn't OpenVMS have POSIX?


It is optional and not up to date with the latest specification.

The problem with POSIX, like any other standard, is that not all systems implement the same POSIX.


I'm not a porter so I'm just trying to understand here, but I would suspect that having POSIX, albeit quirky, would automatically make it easier to port than Windows which has no POSIX. Like porting a web app to IE6 is easier than porting it to a Node CLI app. Does that analogy not work?


Windows has a POSIX implementation.

https://en.wikipedia.org/wiki/Interix


The problem is that each POSIX compatible system tends to have different levels of support for the various POSIX standard versions.

Additionally there are APIs which have undefined edge cases or different limits (e.g. amount of open file handles).

So even if you only target POSIX systems, you have to pollute the code with #ifdef to handle such differences.

It is similar to do web development. There are standards, but each browser version is a different world.


I haven't done any significant amount of porting code. But, wouldn't the fact that almost every OS other than windows is unix-like make porting between those OS's inherently easier than porting to windows?

Besides, the issue explicitly brought up was the fact the Microsoft C++ compiler does not fully support C-11.


I think the issue brought up in the post to which I responded singled out Windows as being specifically difficult to port to, if you use the standard tools for writing native code. This is contrary to my experience, but it's a somewhat common attitude amongst people for whom portability means "targets POSIX". So I thought I'd write a little screed.

As for your other point, it's indeed true that some systems are more like some other systems, and not like others. But so what? If you want your code to be portable, it needs to build on all the targets you support. So you need to do that. Perhaps people assume there's some magic bullet, or secret special thing that you can do? Sadly not, just the usual - work and some forward planning.


> As usual with native code, portability is actually quite easy to achieve - except to Windows using MS's native tools.

I always hear statements like this from people that never did real cross platform development.

There are more operating systems in the world than just plain POSIX and Windows.

Even POSIX if one constrains to POSIX compliant systems, is a bag full of surprises due to undefined behaviours in the standard.


How about "The folly of writing c++11 code without checking the target compiler's c++11 features"?

This is cross-platform coding 101...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: