News for hackers. Stuff that matters.
Re:Brian's Rules for Writing Cross Platform 'C' Code (2008) by mikeash on Saturday June 14, 2014 @02:25PM (#7893289)
UTF-16 is a sad encoding and there's essentially no reason to ever use it except when interfacing with something that insists on it.

UCS-2 made a lot of sense back in the day when Unicode was supposed to be 16-bit and you'd just have one 16-bit "char" for each Unicode code point. Bliss! Then Unicode breached the BMP and this didn't work anymore. UTF-16 is just a way to let all that old code that assumes 16-bit Unicode to keep working. You get all the disadvantages of UTF-8 (no 1:1 correspondence between code units and code points) and none of the advantages (widespread compatibility with non-Unicode-aware tools, mostly-reliable discrimination between actual text and random binary data that might look like text).

One can kind of make a case for UTF-32 in some cases, but UTF-16 is almost never the right choice unless there is literally no other.

Re:Brian's Rules for Writing Cross Platform 'C' Code (2008) by mtdewcmu on Saturday June 14, 2014 @11:53PM (#7894322)
That helps put some things in perspective. Unicode is not a well-understood topic among programmers, I've noticed (at least in the US), and for something so important it's surprisingly difficult to find information. The distinction between UCS-2 and UTF-16 must have made sense at one time, but it makes no sense anymore, and it's not necessarily easy to track down the explanation for why there are two 16-bit formats. Thanks.
Re:Brian's Rules for Writing Cross Platform 'C' Code (2008) by mikeash on Sunday June 15, 2014 @12:23AM (#7894364)
The whole thing is pretty much incomprehensible without understanding the history. It's a bit crazy how much historical baggage Unicode has managed to accumulate in just a couple of decades (and most of it from just the first few years).

It sounds like you have it figured out, but just in case: UCS-2 is the original pure 16-bit encoding from the days when nobody could conceive of needing more than 65536 characters for anything. UTF-16 is the hacked up "oops, it turns out there are a lot more Chinese characters than we realized" version that tries to maintain some compatibility with software built for UCS-2.

Given that there was only a five-year period between the first release of Unicode and the introduction of UTF-16, it's kind of amazing how pervasive the 16-bit encoding got. It's thoroughly baked into Java, where "char" was supposed to be a unicode character, but ended up being a unicode character or a piece of a UTF-16 surrogate pair. Windows APIs and Cocoa's NSString went through the same process. JavaScript too, and the spec still allows implementations to only support UCS-2.

Re:Brian's Rules for Writing Cross Platform 'C' Code (2008) by mtdewcmu on Sunday June 15, 2014 @12:54AM (#7894441)
The c and c++ apis seem to make things worse. The right solution for charset conversion seems to be iconv.
Re:Brian's Rules for Writing Cross Platform 'C' Code (2008) by cpeterso on Saturday June 14, 2014 @03:03PM (#7893381)
btw, the wchar_t typedef is 16 bits for MSVC, but 32 bits for gcc (even for MinG on Windows!). UTF-16 is the worst of all worlds.
Re:Brian's Rules for Writing Cross Platform 'C' Code (2008) by brianwski on Monday June 16, 2014 @10:11PM (#7902517)
Original author here....

This is why we do not use wchar_t as a cross platform type. We like "char *" with NULL terminated Utf8 strings, which works really well on all platforms. Unfortunately on Windows, some of the core API still take Utf16 (2 bytes per char). Since it is a Windows call it must be in an #ifdef anyway, and so IMMEDIATELY BEFORE calling into the Windows call at the last possible moment we convert the string from Utf8 to Utf16. It sounds like a pain, but after you have wrapped all your OS specific calls (like File I/O) you're calling the higher level anyway, and it was completely worth it.