20

I'm looking into learning C basics and syntax before beginning Systems Programming next month. When doing some reading, I came across the C89/99 standards. According to Wikipedia,

C99 introduced several new features, including inline functions, several new data types (including long long int and a complex type to represent complex numbers), variable-length arrays, support for variadic macros (macros of variable arity) and support for one-line comments beginning with //, as in BCPL or C++. Many of these had already been implemented as extensions in several C compilers.

C99 is for the most part backward compatible with C90, but is stricter in some ways; in particular, a declaration that lacks a type specifier no longer has int implicitly assumed. A standard macro STDC_VERSION is defined with value 199901L to indicate that C99 support is available. GCC, Sun Studio and other compilers now support many or all of the new features of C99.

I borrowed a copy of K&R, 2nd Edition, and it uses the C89 standard. For a student, does the use of C89 invalidate some subjects covered in K&R, and if so, what should I look out for?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Jason
  • 11,263
  • 21
  • 87
  • 181

8 Answers8

19

There is no reason to learn C89 or C90 over C99- it's been very literally superseded. It's easy to find C99 compilers and there's no reason whatsoever to learn an earlier standard.

This doesn't mean that your professor won't force C89 upon you. From the various questions posted here marked homework, I get the feeling that many, many C (and, unfortunately, C++) courses haven't moved on since C89.

From the perspective of a starting student, the chances are that you won't really notice the difference- there's plenty of C that's both C99 and C89/90 to be covered.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 9
    "It's easy to find C99 compilers" -- GCC still requires a `-std=c99` flag and Microsoft apparently doesn't support it properly http://stackoverflow.com/questions/2656080/vs-2008-and-c99 – Fred Foo Dec 05 '10 at 13:37
  • 1
    @larsmans: So, GCC completely supports it, and there are dozens of C compilers available for Windows. As for Microsoft, if you have a C++ compiler, you'd have to be insane to go back to C, so their lack of C99 support is no big deal. – Puppy Dec 05 '10 at 13:39
  • @DeadMG: I disagree regarding the C++ compiler... but +1 for going for C99 anyway. – Matt Joiner Dec 05 '10 at 13:41
  • 2
    Fair enough, +1 for the answer. I don't agree that "going back" to C is an insane move, though. I'm a C++ programmer by profession, but I still love C for its minimalism. – Fred Foo Dec 05 '10 at 13:42
  • @larsmans: You mean like, how it misses out on a whole bunch of really, really useful things, and how you could program C++ without those things, if you really, really wanted to? – Puppy Dec 05 '10 at 14:12
  • @DeadMG: No, I mean seeing through the forest of `private`, `protected`, `public`, `friend` and `template` how data structures can be implemented in a very simple way. (I wouldn't write production code in C anymore, but prototyping algorithms in C tends to make them a lot simpler.) – Fred Foo Dec 05 '10 at 14:47
  • 2
    @DeadMG: GCC does *not* completely support C99, there are some omissions (generally negligible, but worse on some platforms than others). – Steve Jessop Dec 05 '10 at 15:44
  • @Steve: Was that really worthy of a downvote? There's still no reason to junk all the features that ARE supported. – Puppy Dec 05 '10 at 16:07
  • 1
    No, the downvote is for "there's no reason whatsoever to learn an earlier standard", which is quite simply false. The reasons for using C89 are niche and getting rarer, that's isn't the same thing as non-existent. I'm also not sure it's true that a student won't notice the difference - if you don't then what you're writing is far closer to C89 than idiomatic C99: certainly no advantage is being taken of new features in C99. As you say, giving up those new features is not a good idea unless the course teachers are absolutely demanding that submitted code compiles as C89. – Steve Jessop Dec 05 '10 at 16:11
  • @Steve: Right. So I'm a student, and I'm going to learn the earlier standard, because some compilers might not support every single feature I learn about. – Puppy Dec 05 '10 at 16:28
  • 1
    Regarding "going back", C++ has few useful features over C if you care about keeping your code efficient and fail-safe, and lots of annoyances, particularly the insane approach to type enforcement and the necessity of explicit casts. – R.. GitHub STOP HELPING ICE Dec 05 '10 at 17:34
  • I agree that he should learn C99, but I don't agree that: "It's easy to find C99 compilers and there's no reason whatsoever to learn an earlier standard." The company I work for has a large system written in C that needs to compile with GCC and several versions of Visual Studio. All the code we write has to be C89 compliant, otherwise Visual Studio will complain loudly. – sdfqwerqaz1 Nov 15 '13 at 08:03
  • Microsoft never did things right when it comes to C and C++ (no support for 50% of C++11 features, not to mention C++14... and of top of that - `wmain`? Seriously?!) I know it might fix some of these in Visual Studio 2015 but I, for one, don't care about someone who is always so late with everything and "supersedes" POSIX with some silly `wcscpy_s` all over the place. – rr- Jul 01 '15 at 07:06
  • @puppy "As for Microsoft, if you have a C++ compiler, you'd have to be insane to go back to C" What? Why? These two languages are different and have different usages. It's like saying that orange is an improved apple. – rr- Jul 01 '15 at 07:07
11

Use the C99 standard, it's newer and has more features. Particularly useful may be the bool type in <stdbool.h> and the int32_t etc. family of types; the latter prevents a lot of unportable code that relies on ints having a certain size. AFAIK, it doesn't invalidate K&R, though some example programs may be written in a slightly different style now.

Note that some compilers still don't support C99 properly. I believe that GCC still requires the use of a -std=c99 flag to enable it; many Unix/Linux systems have a c99 command that wraps GCC and enables C99.

The same goes for many university professors. I surprised mine by handing in a program that used bool in my freshman year. He'd never heard of that type in C :)

Community
  • 1
  • 1
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
4

While I generally agree with the others, it is worth noting that K&R is such a good book that it might be worth learning C from it and then updating your knowledge as you read about the C99 standard.

neo2862
  • 1,496
  • 1
  • 13
  • 27
  • 2
    Am I the only person who doesn't think K&R is the greatest book to learn C from? It is indeed a classic CS text, but I am not sure it is great for beginners. Probably best to learn the newer standards and styles. – in70x May 26 '14 at 19:48
3

If you are at student level you probably won't even notice the differences.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    the C99/C++ comments `//`, `(u)intN_t, declarations after code and printfs `%z` are some things which are very likely to notice. At least if you learn c not in a bad way. – 12431234123412341234123 Jan 03 '17 at 16:41
2

Yes, it's a bit odd that you can get a loud consensus that K&R is a great C book, and also a loud consensus that C99 is the correct/current/best version of C. The two positions are incompatible - even if K&R is the best book available to learn "C meaning C99", that just implies the rest are rubbish, or are also hopelessly outdated.

I would advise learning and using C99, but keeping an eye to C89 as you do so. If you use a compiler that has both C89 and C99 compliant modes, then you can write a few bits of C89 just to get an idea of the differences. Then if you ever need to write some code intended to be portable to places that C99 doesn't go, you'll know what to do. If you never have to write any such code, then you've wasted perhaps a day.

Writing C89 properly is actually surprisingly difficult, because getting hold of a copy of the C89 standard is difficult. So, C99 if you can, C89 if for some odd reason you have to, and have some awareness what the difference is. Maybe use K&R to cover the very basics, but get a look at some idiomatic C99 as soon as possible.

As for specific issues to be aware of when reading K&R: there's a list of major changes in the foreword of the standard (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf), although the details aren't laid out there. A lot of them are new features added to C99, so it's not that K&R is wrong, it just may not always use the best tools for a given job. Some of them are quite fiddly things where you should probably consult the standard if you need the details anyway. The rest are things removed from C89, that usually a C99 compiler will tell you about as and when you try to use them.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

As a student, that doesn't influence you so much. But if possible, you should find a new C book which covers C99

Huang F. Lei
  • 1,835
  • 15
  • 23
1

While I think it's beneficial to know which features are more recent and less likely to be supported by obscure (or intentionally-broken, like MSVC) compilers, there are a few C99 features that you should absolutely use:

  • snprintf: This is the definitive function for safe and clean string assembly in C. If your compiler is missing it, you can either replace the whole printf subsystem (probably a good idea since most implementations with missing snprintf are also full of (often intentional) bugs in printf behavior), or wrap tmpfile/fprintf/fread/fclose.

  • stdint.h: If you need fixed-size types (16/32/64-bit), use the standard names int16_t, uint16_t, int32_t, etc. Do not invent your own, and absolutely don't use system-specific ones like INT64 or u32. It just makes your code ugly and hard to integrate and reuse. If your compiler is missing stdint.h, just drop in your own to define the types in terms of the correct-for-your-platform types.

  • Specifically uint64_t, in place of int foo[2]; or struct { int lo, int hi; } foo; or other hideous legacy hacks to work with 64-bit numbers. Any sane compiler even without C99 support has its own 64-bit types you can use to define int64_t and uint64_t.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
1

The term "C89" describes two very different languages:

  1. The language that programmers in 1989 thought the Committee was describing in places where the Standard was ambiguous, and which supported features that were common in pre-existing implementations.

  2. The language that the Committee has since decided that it wanted to have described, which threw compatibility with existing functionality out the window.

C99 "clarifies" ambiguous parts of the standard by saying that they meant to have the Standard interpreted in a way that would have broken a substantial fraction of existing code and made it impossible to perform many tasks as efficiently as they had been performed in C before 1989.

The right language to program in, for many applications, would be the superset of pre-Standard C, C89, C99, and C11. It's important, however, that anyone programming in that language be clear that they're using that language rather than a shrinking subset which favors speed over reliability.

supercat
  • 77,689
  • 9
  • 166
  • 211