20

It's 2012. I'm writing some code in C. Should I be still be using C89? Are there still compilers that do not support C99?

I don't mind using /* */ instead of //.

I'm not sure about C89 forbids mixing declarations and code. I'm kind of leaning towards the idea that it's actually more readable to have all the declarations in one place, and if it isn't, the function is too long.

VLAs look useful but I haven't needed them yet.

Should I stick with C89 if I don't have a compelling reason not to? Are there other things I haven't considered?

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
mk12
  • 25,873
  • 32
  • 98
  • 137
  • 10
    Bottom line: use C99 unless you need to support MSVC, in which case you're stuck with C89. – Paul R Aug 12 '12 at 21:37
  • 2
    Note that VLAs were made optional in C11, due to implementation difficulty. – Dietrich Epp Aug 12 '12 at 21:44
  • @DietrichEpp, where do you get this "implementation difficulty" from? I understood that it only was to calm the ideology that people are making out of this down. – Jens Gustedt Aug 12 '12 at 22:17
  • @JensGustedt: The C11 rationale hasn't been published yet, so it's partly speculation. However, if you were to sit down and try to add VLA support to an existing compiler, you'd see how deeply it changes your assumptions about e.g. how to implement a type system for C. – Dietrich Epp Aug 12 '12 at 22:36
  • 1
    Unfortunately the part that affects the type system is the valuable part of VLA's. I would have had no problem with them making it optional to support VLA's of automatic storage duration, but pointer-to-VLA (for VLA obtained by `malloc`) is essential to writing clean mathematical code. – R.. GitHub STOP HELPING ICE Aug 12 '12 at 22:42
  • In my opinion, three of the most useful features in C99 are `long long`, `snprintf()` and designated initalisers (`struct foo x = { .a = 5, .j = 1 };`) – caf Aug 13 '12 at 01:28
  • In 2015, you should use the [C11](http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29) standard, at least on machines with a recent version of [GCC](http://gcc.gnu.org/) or [Clang/LLVM](http://clang.llvm.org/) since it is becoming the default C version on these compilers. BTW, both `atomic` support and [flexible array members](http://en.wikipedia.org/wiki/Flexible_array_member) are very useful features (unavailable in C89). – Basile Starynkevitch Feb 21 '15 at 20:34
  • @BasileStarynkevitch: Unfortunately, language in the C11 standard which the authors may have intended to allow out-of-order execution of code which isn't expected to have side-effects, but might overflow, access invalid pointers, or otherwise trap, has been interpreted as an invitation for the authors of compilers which target platforms where certain behaviors not mandated by the standard would "naturally" have been useful (e.g. on most platforms, the most efficient way of implementing `<` for related pointers will *also* define a total ordering of *all* pointers, such that... – supercat May 11 '15 at 21:14
  • ...one may compare arbitrary pointers and assume that if `p > q`, then `p+n > q` for any positive `n` that can be legitimately added to `p`.) The standard imposes no requirements on what `<` will do given unrelated pointers (it's Undefined Behavior) but some compilers on platforms which could easily make `<` define a global ranking among unrelated pointers instead use the fact that unrelated-pointer comparisons are Undefined Behavior as an excuse to make such comparisons negate the laws of time *and causality*. – supercat May 11 '15 at 21:22
  • 1
    "we may be able to move up to a newer stdc model eventually, but right now the newer models have some annoying deficiencies, so the traditional "gnu89" model ends up being the preferred one." quote from a Linux kernel commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=51b97e354ba9fce1890cf38ecc754aa49677fc89 – hexicle Jan 07 '18 at 00:19

4 Answers4

17

Unless you know that you cannot use a C99-compatible compiler (the Visual Studio C compiler is the most prominent candidate) there is no good reason for not using the nice things C99 gives you.

However, even if you need to support that compiler you can use some C99 features - just not all of them.

One feature of C99 that is incredibly handy is being able to do for(int i = ...) instead of having to declare your loop variable on top of the function - especially since C actually has a block scope. That's the kind of declaration where having it on top really doesn't improve the readability.

Community
  • 1
  • 1
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 2
    Visual Studio 2013 is now supporting some C99 functionalities. See http://blogs.msdn.com/b/vcblog/archive/2013/06/27/what-s-new-for-visual-c-developers-in-vs2013-preview.aspx – Étienne Nov 04 '13 at 23:14
  • 3
    You can workaround the problem in your example by doing `{int i;for(i=...)...}`. – Ruslan Aug 26 '16 at 15:30
10

There is a reason (or many) why C89 was superseded by C99. If you know for sure that no C99 compiler is available for your particular piece of work (unlikely unless you are stuck with Visual Studio which never supported C officially anyway), then you need to stay with C89 but otherwise you should certainly put yourself in a position where you can benefit from the last 20+ years of improvement. There is nothing inherently slower about C99.

Perhaps you should even consider looking at the newest C11 standard. There has been some important fixes for dealing with Unicode that any C programmer could benefit from (other changes in the standard are absolutely minimal)...

Mathias Schwarz
  • 7,099
  • 23
  • 28
  • 1
    Perhaps 'never supported C' is an overstatement but they made it clear that the C they support is the part of C that is a subset of C++, so they only support what they can get from crippling the C++ compiler. – Mathias Schwarz Aug 12 '12 at 21:38
  • They definitely don't support the wide character supplement to C89, and if I remember correctly there are even some conformance issues for original C89... – R.. GitHub STOP HELPING ICE Aug 12 '12 at 22:43
7

Good code is a mixture of performance, scalability, readability, and maintainability.

In my opinion, C99 makes code easier to read and maintain. Very, very few compilers don't support C99, so I say go with it. Use the tools you have available, unless you are certain you will need to compile your project with a compiler that requires the earlier standard.

Check out these links to learn more about the advantages to C99:

http://www.kuro5hin.org/?op=displaystory;sid=2001/2/23/194544/139

http://en.wikipedia.org/wiki/C99#Design

Note that C99 also supports library functions such as snprintf, which are very useful, and have better floating point support. Also, I find macros to be extremely helpful, especially when working with math-intensive applications (like cryptographic algorithms)

cegfault
  • 6,442
  • 3
  • 27
  • 49
5

I disagree with Paul R's "bottom line" comment. There are multiple cases where C89 is advantageous for portability.

  1. Targeting embedded systems, which may or may not have compilers supporting C99: https://groups.google.com/forum/#!topic/comp.arch.embedded/WNvhw3T_9pI%5B1-25%5D

  2. Targeting the TinyCC compiler, as might be required in a restricted environment where installing a gigantic toolchain is either impractical or not allowed. (TCC is no longer being developed, and Bellard's last statement as to ISOC99 support was that it was "heading towards" full compliance.)

  3. Supporting dynamic compilation via libtcc (see above).

  4. Targeting MSVC, as others have noted.

  5. For source-compatibility with projects that may be required by their company to use the C89 standard. This is especially relevant if you're writing an open source library, and want to maximize its application in some industry.

As cegfault noted, some of the C99 features as listed on Wikipedia can be very useful, but none I would consider indispensable if your priority is portability, or any of the above reasons apply.

It appears Microsoft hasn't budged on C99 compliance. SimonRev from Beijer Electronics commented on a related MSDN thread in November 2016:

In broad strokes, the only parts of the C99 compiler that were implemented are those parts that they needed to keep the C++ compiler up to date.

Microsoft has done basically nothing to the C compiler since VC6, and they haven't made much secret that C++ is their vision of the future of native code, not C.

In conclusion, if you want portability for embedded or restricted systems, dynamic compilation, MSVC, or compatibility with proprietary source code, I would say C89 is advantageous.