Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> The problem is, if I want my C code to compile with MSVC, it has to compile as C++

As someone who has compiled a lot of .c files that do not cast void pointers with cl.exe, I'd say no, this is not true... Maybe what you're trying to say is that your code relies on C99 features that are also present in C++? IMO if that's what's holding you back it's much easier to just write C89, maybe with the occasional ifdef, than to suddenly write some crummy C/C++ hybrid. That or just use mingw. (Unless you're doing SEH. I'm not aware of a good way to do SEH with mingw.)



You're suggesting I write C89 in 2013 just to support MSVC? C89 in which you can't even mix data and code?

I think casting void pointers is very much the lesser of two evils. And of course I can use MinGW, but that doesn't mean the majority of Windows developers don't insist on using MSVC.


C++ is not a superset of C[0]. If you want to use MSVC and newer features, then you're not writing C anymore; you're just writing an awkward C++ program.

[0] http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B


Nope, I'm definitely writing C99, but it just so happens that MSVC is happy enough pretending it's C++.

Definitely writing C99 in that I compile the exact same source files with -std=c99 -Wall -pedantic when using a real C compiler.


> C89 in which you can't even mix data and code?

I don't think this is as big a deal as you're making it out to be. Maybe I'm just used to it, but this is one area where I consider the C89 way to be better on stylistic grounds. (I wrote about this on a stack exchange site some time ago: http://programmers.stackexchange.com/questions/75039/why-dec...)

Realistically I don't think C99 is all that revolutionary, and the fact is there are plenty of people writing C89 in 2013. Let's look at some things C99 adds over C89:

* Mixed declarations and code

IMO not a huge deal, for reasons I give above.

* VLAs

A nice feature, but people have been using malloc for similar purposes for ages, so it's hard to say it's any better than "nice to have". I'd also argue that something that leads me to potentially consume arbitrary amounts of stack space based on runtime decisions is probably not universally good, and I'm pretty cautious about using VLAs even when given the choice.

* Last field of a struct can be variable sized array, eg. struct foo { int num_data; int data[]; };

I like this pattern and have used it a lot. Including with VC++ by having a zero-sized array at the end of the struct. This is once place where I use an ifdef to bridge the gaps because recently I noticed LLVM started doing weird things for this if you don't do it the "legit" C99 way.

* Cosmetic issues like // comments

VC++ already supports this in C89 files as a non-portable extension.

* Portable typedefs like uint32_t, etc.

These are also pretty handy. But if you're building with VC++ you're probably using the non-portable Microsoft ones anyway. (I think VC++ 2010 added the C99 versions too.)

* bool type

Again, every platform and even reasonably sized library works around this with a typedef and some macros.

* Slightly different behaviors for some libc functions

I notice this most for snprintf, where the pre-C99 return value [followed by Microsoft] means something different [and better] in C99. Again there are non-portable solutions for this that you can use ifdefs for.

* Named initializers for struct members

Cool feature. I'd hardly say I couldn't live without it, though. The only place I've really seen it used extensively is in the Linux kernel.

* Stuff that no one uses, such as "static" as used in these slides, or complex numbers, or whatever.

Not a problem since these don't see wide use.


Mixed declarations and code are absolutely essential in a modern C programming style. It's all very well to declare things like "your functions should be shorter" or "you shouldn't use temporary variables in macros", but it's just not practical in real world code. In fact, it's so impractical they amended the spec 14 years ago.

Then there are things like the portable integer types - which you decided aren't necessary because everyone is writing Win32 code (???), the designated initializers which I use every day to make my struct initializing code safe from changes in the struct itself, for loops, a consistent bool type ... heck, I could go on all day if you hadn't already dismissed the rest of the standard as "stuff that no one uses".

I really don't mean to come across as aggressive, but this kind of ignorant and dismissive attitude is so rampant in the tech scene at the moment. And it's getting us nowhere.


Not meaning you to make you feel like you're inching towards the aggressive, I just feel like the distance between C89 and C99 is not a very big one. Even in C99 I tend to use some perhaps conservative style choices, and in this view the C99 stuff really does seem like "niceties" rather than essentials. The difference between C and C++ feels much bigger to me.

And then after all, you initially explained the need for this in terms of Windows-specific code (or at least that's how I read it), so that's the angle I took...




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

Search: