Does C have 32 or 44 keywords? - c

ISO/IEC 9899:2017 C N2176 document link: https://files.lhmouse.com/standards/ISO%20C%20N2176.pdf
There are plenty of sources on world wide web, which say that there are 32 keywords in C langauge, But this document (I think it's a draft version, but there's no much changes as compared to the previous version, right?) has 44 words that are defined to the keywords of C language.
Please explain this.
============================================================
Link to the sources which say that there are 32 keywords in C language:
https://www.programiz.com/c-programming/list-all-keywords-c-language
https://tutorials.webencyclop.com/c-language/c-keyword/
https://www.educba.com/c-keywords/
https://www.javatpoint.com/keywords-in-c
https://beginnersbook.com/2014/01/c-keywords-reserved-words/
https://www.phptpoint.com/c-keywords/
https://www.guru99.com/c-tokens-keywords-identifier.html
https://fresh2refresh.com/c-programming/c-tokens-identifiers-keywords/
https://www.w3schools.in/c-tutorial/keywords/
Note: Some of these sites are useful for beginners to learn basic concepts and terminalogies of C.

The claims of there being "32" keywords in C refer to the original ANSI-specified version of C from 1989, aka C89.
Because this is the Internet, and because the real C specifications are behind ISO's ridiculous paywall most people so-inclined probably can't fact-check the claim.
And it's not a claim worth fact-checking: the number of keywords in a language is utter trivia of no consequence.
The ISO/IEC 9899 specification you linked to refers to C17 (the proposed updated C specification in 2017) which postdates C89 by 28 years.
It should come as no surprise that a future updated revision of a programming language introduces new keywords.
Historically, when C was introduced, people were impressed by its minimalist syntax and how the language's design effectively reified everything by implementing functionality as library features instead of language features which is what keeps C simple and helps mitigate every language's designer's fears about feature creep.
In comparison, C's early contemporaries like COBOL, opted to implement functionality into their own languages as first-class features, which is why COBOL has over 300 keywords; so I'll admit that using the stark difference in keyword-count does serve as a proxy for language-complexity and by extension: a way to almost quantify good design. But using it as the basis for comparing languages today in 2021 is of limited-utility as the most relevant programming languages today1 are already either inspired by C or derived from it somehow, and they all share C's decision to do things in the library instead of the language, so all those languages similarly have a low keyword count compared to COBOL, SQL, and others, and so that's why C's keyword count just isn't interesting anymore.
1: C-inspired or C-derived languages in use today: C++, Objective-C, Java, Groovy, Swift, C#, JavaScript, TypeScript, Go, PHP, Perl. Other popular languages that aren't modelled on C (like Haskell, OCaml, etc) do share C's library-first philosophy, but I can't say if C originated it or not - but I feel that languages opting for library-first designs is inevitable: the cost to implement language-features is easily ten-fold that of implementing library features.

Related

Are there any interpreted agent languages that CANNOT BE or ARE NOT compiled?

Regarding the three criteria of agent-oriented programming paradigm:
support a logical system for defining the mental state of agents
interpreted programming language for programming agents
agentification process, for compiling agent programs into low-level executable systems (tied into second point)
Are there interpreted programming languages that are not compiled? To my understanding, the whole point of interpreting languages is to implement a new language with certain features, syntax, etc... but the underlying implementation eventually needs to compile down into something low-level so that it can actually be executed.
Is point 3 of the agent-oriented programming paradigm simply saying that it isn't sufficient to just theoretically define a language without implementing the language in something that can compile down into low-level code that can actually be run?
Yes, Jason is fully interpreted. It is a BDI agent platform. It also supports dynamic (on-the-fly) programming. You can add and organize plans in runtime and you can also save the agent mental state and load a new content with the whole system running.
Actually, there is a continuum between compiled and interpreted languages. And being compiled or interpreted is a property of the language implementation (a programming language is a specification, that is a document like R5RS; it is not a software)
I strongly recommend reading Quiennec's Lisp In Small Pieces book, which explains that in great detail (see also this). I also recommend reading Scott's Programming Language Pragmatics book.
BTW, Minsky's Society of Mind book and Pitrat's Artificial Beings: The Conscience of a Conscious Machine book should also interest you. And J.Pitrat's blog is also relevant.
Many "compiled" languages have "interpreted" parts. For example, in C, most printf implementations are "interpreting" the control format string (this is done in the printf function of the C standard library), even if the specification permits some form of "compilation". (and sometimes, GCC or Clang might be clever enough...)
Are there interpreted programming languages that are not compiled?
Read also about partial evaluation and Futamara projections
Study Common Lisp and look inside its SBCL implementation, which compiles into machine code every REPL interaction. Look also into LuaJit.
Be also aware of JIT-compiling libraries such as libgccjit, GNU lightning, asmjit, or LLVM.

JSF (Joint Strike Fighter) like standard for C

There is the well-known Joint Strike Fighter (JSF) standard for C++. Is there a similar standard for C which promotes the use of C programmers' quality when coding for mission-critical platform?
There is MISRA C by the Motor Industry Software Reliability Association:
MISRA-C:2004, Guidelines for the use of the C language in critical systems
Les Hatton has specified an ISO C subset for critical systems and has written quite a bit about MISRA C. I'd read through (at least most of) what he has to say before making any decisions.
If you're in TLDR mode, the short answer is that most such guidelines (including MISRA C) include rules running the entire gamut from extremely useful to somewhat useful, to a few that are probably actively harmful (e.g., editing code to follow them is more likely to introduce bugs than fix anything).

Has the use of C to implement other languages constrained their designs in any way?

It seems that most new programming languages that have appeared in the last 20 years have been written in C. This makes complete sense as C can be seen as a sort of portable assembly language. But what I'm curious about is whether this has constrained the design of the languages in any way. What prompted my question was thinking about how the C stack is used directly in Python for calling functions. Obviously the programming language designer can do whatever they want in whatever language they want, but it seems to me that the language you choose to write your new language in puts you in a certain mindset and gives you certain shortcuts that are difficult to ignore. Are there other characteristics of these languages that come from being written in that language (good or bad)?
I tend to disagree.
I don't think it's so much that a language's compiler or interpreter is implemented in C — after all, you can implement a virtual machine with C that is completely unlike its host environment, meaning that you can get away from a C / near-assembly language mindset.
However, it's more difficult to claim that the C language itself didn't have any influence on the design of later languages. Take for example the usage of curly braces { } to group statements into blocks, the notion that whitespace and indentation is mostly unimportant, native type's names (int, char, etc.) and other keywords, or the way how variables are defined (ie. type declaration first, followed by the variable's name, optional initialization). Many of today's popular and wide-spread languages (C++, Java, C#, and I'm sure there are even more) share these concepts with C. (These probably weren't completely new with C, but AFAIK C came up with that particular mix of language syntax.)
Even with a C implementation, you're surprisingly free in terms of implementation. For example, chicken scheme uses C as an intermediate, but still manages to use the stack as a nursery generation in its garbage collector.
That said, there are some cases where there are constraints. Case in point: The GHC haskell compiler has a perl script called the Evil Mangler to alter the GCC-outputted assembly code to implement some important optimizations. They've been moving to internally-generated assembly and LLVM partially for that reason. That said, this hasn't constrained the language design - only the compiler's choice of available optimizations.
No, in short. The reality is, look around at the languages that are written in C. Lua, for example, is about as far from C as you can get without becoming Perl. It has first-class functions, fully automated memory management, etc.
It's unusual for new languages to be affected by their implementation language, unless said language contains serious limitations. While I definitely disapprove of C, it's not a limited language, just very error-prone and slow to program in compared to more modern languages. Oh, except in the CRT. For example, Lua doesn't contain directory functionality, because it's not part of the CRT so they can't portably implement it in standard C. That is one way in which C is limited. But in terms of language features, it's not limited.
If you wanted to construct an argument saying that languages implemented in C have XYZ limitations or characteristics, you would have to show that doing things another way is impossible in C.
The C stack is just the system stack, and this concept predates C by quite a bit. If you study theory of computing you will see that using a stack is very powerful.
Using C to implement languages has probably had very little effect on those languages, though the familiarity with C (and other C like languages) of people who design and implement languages has probably influenced their design a great deal. It is very difficult to not be influenced by things you've seen before even when you aren't actively copying the best bits of another language.
Many languages do use C as the glue between them and other things, though. Part of this is that many OSes provide a C API, so to access that it's easy to use C. Additionally, C is just so common and simple that many other languages have some sort of way to interface with it. If you want to glue two modules together which are written in different languages then using C as the middle man is probably the easiest solution.
Where implementing a language in C has probably influenced other languages the most is probably things like how escapes are done in strings, which probably isn't that limiting.
The only thing that has constrained language design is the imagination and technical skill of the language designers. As you said, C can be thought of as a "portable assembly language". If that is true, then asking if C has constrained a design is akin to asking if assembly has constrained language design. Since all code written in any language is eventually executed as assembly, every language would suffer the same constraints. Therefore, the C language itself imposes no constraints that would be overcome by using a different language.
That being said, there are some things that are easier to do in one language vs another. Many language designers take this into account. If the language is being designed to be, say, powerful at string processing but performance is not a concern, then using a language with better built-in string processing facilities (such as C++) might be more optimal.
Many developers choose C for several reasons. First, C is a very common language. Open source projects in particular like that it is relatively easier to find an experienced C-language developer than it is to find an equivalently-skilled developer in some other languages. Second, C typically lends itself to micro-optimization. When writing a parser for a scripted language, the efficiency of the parser has a big impact on the overall performance of scripts written in that language. For compiled languages, a more efficient compiler can reduce compile times. Many C compilers are very good at generating extremely optimized code (which is also part of the reason why many embedded systems are programmed in C), and performance-critical code can be written in inline assembly. Also, C is standardized and is generally a static target. Code can be written to the ANSI/C89 standard and not have to worry about it being incompatible with a future version of C. The revisions made in the C99 standard add functionality but don't break existing code. Finally, C is extremely portable. If at least one compiler exists for a given platform, it's most likely a C compiler. Using a highly-portable language like C makes it easier to maximize the number of platforms that can use the new language.
The one limitation that comes to mind is extensibility and compiler hosting. Consider the case of C#. The compiler is written in C/C++ and is entirely native code. This makes it very difficult to use in process with a C# application.
This has broad implications for the tooling chain of C#. Any code which wants to take advantage of the real C# parser or binding engine has to have at least one component which is written in native code. This eventually results in most of the tooling chain for the C# language being written in C++ which is a bit backwards for a language.
This doesn't limit the language per say but definitely has an effect on the experience around the language.
Garbage collection. Language implementations on top of Java or .NET use the VM's GC. Those on top of C tend to use reference counting.
One thing I can think of is that functions are not necessarily first class members in the language, and this is can't be blamed on C alone (I am not talking about passing a function pointer, though it can be argued that C provides you with that feature).
If one were to write a DSL in groovy (/scheme/lisp/haskell/lua/javascript/and some more that I am not sure of), functions can become first class members. Making functions first class members and allowing for anonymous functions allows to write concise and more human readable code (like demonstrated by LINQ).
Yes, eventually all of these are running under C (or assembly if you want to get to that level), but in terms of providing the user of the language the ability to express themselves better, these abstractions do a wonderful job.
Implementing a compiler/interpreter in C doesn't have any major limitations. On the other hand, implementing a language X to C compiler does. For example, according to the Wikipedia article on C--, when compiling a higher level language to C you can't do precise garbage collection, efficient exception handling, or tail recursion optimization. This is the kind of problem that C-- was intended to solve.

Is there a new upcoming C Standard that supersedes C99?

Is there a new upcoming C Standard that supersedes C99? After all there's an unofficial C++0x coming out as per the source in Wikipedia here. For the sake of this question, let's call this C99 superset as C'y2k.01' to not confuse (as I was going to say C99++ which looks like the C++ counterpart.... but I digress)
If there isn't, what would you like to see in the C'y2k.01' standard today in order for the C language to survive in the 21st century? Sure there's Java, .NET, C#, Scala, Erlang, F# to name but a few, but really, go on...
I would like to see:
Unifying the Posix functions into the runtime,
with the #1 mentioned above, fork()ing would be much easier and parallelizing the code would be made possible instead of relying on a third party library
The ease of dynamic memory for custom collections such as arrays ... something like this 'char __dynamic foo[];' where you can add/remove elements easily
This is open to debate and discussion.
Thanks.
There is a project in place to update C99. The draft is currently dubbed C1X and is available here. You can also see the charter.
You can see a list of the currently open projects and get up to date news from the ISO C Working Group.

The Definitive C Book Guide and List

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
This question attempts to collect a community-maintained list of quality books on the c programming language, targeted at various skill levels.
C is a complex programming language that is difficult to pick up on-the-go by reading online tutorials. A comprehensive book is often the best way to learn the language, and finding a good book is the first step. It is important to avoid badly-written books, and even more importantly, books that contain serious technical errors.
Please suggest edits to the accepted answer to add quality books, with an approximate skill level and a short blurb/description about each book. (Note that the question is locked, so no new answers will be accepted. A single answer is being maintained with the list)
Feel free to debate book choices, quality, headings, summaries, skill levels, and anything else you see that is wrong. Books that are deemed satisfactory by the C community here will stick around on the list; the rest will be regularly removed.
For books that have reviews by the Association of C and C++ Users (ACCU), a link to those reviews should be added along with the book.
See also:
Other C-related resources in the c tag wiki
A similar list for c++: The Definitive C++ Book Guide and List
This question was discussed on Meta as part of the Deleted Questions Audit 2018.The consensus was to keep it undeleted and actively maintained.
Warning!
This is a list of random books of diverse quality. In the view of some people (with some justification), it is no longer a list of recommended books. Some of the listed books contain blatantly incorrect statements or teach wrong/harmful practices. People who are aware of such books can edit this answer to help improve it.
See The C book list has gone haywire. What to do with it?, and also Deleted question audit 2018.
Reference (All Levels)
The C Programming Language (2nd Edition) - Brian W. Kernighan and Dennis M. Ritchie (1988). Still a good, short but complete introduction to C (C90, not C99 or later versions), written by the inventor of C. However, the language has changed and good C style has developed in the last 25 years, and there are parts of the book that show its age.
C: A Reference Manual (5th Edition) - Samuel P. Harbison and Guy R. Steele (2002). An excellent reference book on C, up to and including C99. It is not a tutorial, and probably unfit for beginners. It's great if you need to write a compiler for C, as the authors had to do when they started.
C Pocket Reference (O'Reilly) - Peter Prinz and Ulla Kirch-Prinz (2002).
The comp.lang.c FAQ - Steve Summit. Web site with answers to many questions about C.
Various versions of the C language standards can be found here. There is an online version of the draft C11 standard.
The new C standard - an annotated reference (Free PDF) - Derek M. Jones (2009). The "new standard" referred to is the old C99 standard rather than C11.
Rationale for C99 Standard.
Beginner
C Programming: A Modern Approach (2nd Edition) - K. N. King (2008). A good book for learning C.
Programming in C (4th Edition) - Stephen Kochan (2014). A good general introduction and tutorial.
C Primer Plus (5th Edition) - Stephen Prata (2004)
A Book on C - Al Kelley/Ira Pohl (1998).
The C Book (Free Online) - Mike Banahan, Declan Brady, and Mark Doran (1991).
C: How to Program (8th Edition) - Paul Deitel and Harvey M. Deitel (2015). Lots of good tips and best practices for beginners. The index is very good and serves as a decent reference (just not fully comprehensive, and very shallow).
Head First C - David Griffiths and Dawn Griffiths (2012).
Beginning C (5th Edition) - Ivor Horton (2013). Very good explanation of pointers, using lots of small but complete programs.
Sams Teach Yourself C in 21 Days - Bradley L. Jones and Peter Aitken (2002). Very good introductory stuff.
C In Easy Steps (5th Edition) - Mike McGrath (2018). It is a good book for learning and referencing C.
Effective C - Robert C Seacord (2020). A good introduction to modern C, including chapters on dynamic memory allocation, on program structure, and on debugging, testing and analysis. It has some pointers toward probable C2x features.
Intermediate
Modern C — Jens Gustedt (2017 1st Edn; 2019 2nd Edn). Covers C in 5 levels (encounter, acquaintance, cognition, experience, ambition) from beginning C to advanced C. It covers C11 and C17, including threads and atomic access, which few other books do. Not all compilers recognize these features in all environments.
C Interfaces and Implementations - David R. Hanson (1997). Provides information on how to define a boundary between an interface and implementation in C in a generic and reusable fashion. It also demonstrates this principle by applying it to the implementation of common mechanisms and data structures in C, such as lists, sets, exceptions, string manipulation, memory allocators, and more. Basically, Hanson took all the code he'd written as part of building Icon and lcc and pulled out the best bits in a form that other people could reuse for their own projects. It's a model of good C programming using modern design techniques (including Liskov's data abstraction), showing how to organize a big C project as a bunch of useful libraries.
The C Puzzle Book - Alan R. Feuer (1998)
The Standard C Library - P.J. Plauger (1992). It contains the complete source code to an implementation of the C89 standard library, along with extensive discussions about the design and why the code is designed as shown.
21st Century C: C Tips from the New School - Ben Klemens (2012). In addition to the C language, the book explains gdb, valgrind, autotools, and git. The comments on style are found in the last part (Chapter 6 and beyond).
Algorithms in C - Robert Sedgewick (1997). Gives you a real grasp of implementing algorithms in C. Very lucid and clear; will probably make you want to throw away all of your other algorithms books and keep this one.
Pointers on C - Kenneth Reek (1997).
Problem Solving and Program Design in C (6th Edition) - Jeri R. Hanly and Elliot B. Koffman (2009).
Data Structures - An Advanced Approach Using C - Jeffrey Esakov and Tom Weiss (1989).
C Unleashed - Richard Heathfield, Lawrence Kirby, et al. (2000). Not ideal, but it is worth intermediate programmers practicing problems written in this book. This is a good cookbook-like approach suggested by comp.lang.c contributors.
Object-oriented Programming with ANSI-C (Free PDF) - Axel-Tobias Schreiner (1993).
The code gets a bit convoluted. If you want C++, use C++. It only uses C90, of course.
Expert
Expert C Programming: Deep C Secrets - Peter van der Linden (1994). Lots of interesting information and war stories from the Sun compiler team, but a little dated in places.
Advanced C Programming by Example - John W. Perry (1998).
Advanced Programming in the UNIX Environment - Richard W. Stevens and Stephen A. Rago (2013). Comprehensive description of how to use the Unix APIs from C code, but not so much about the mechanics of C coding.
Uncategorized
Essential C (Free PDF) - Nick Parlante (2003). Note that this describes the C90 language at several points (e.g., in discussing // comments and placement of variable declarations at arbitrary points in the code), so it should be treated with some caution.
C Programming FAQs: Frequently Asked Questions - Steve Summit (1995). This is the book of the web site listed earlier. It doesn't cover C99 or the later standards.
C in a Nutshell - Peter Prinz and Tony Crawford (2005). Excellent book if you need a reference for C99.
C in a Nutshell (2nd Ed.) - Peter Prinz and Tony Crawford (2016), a reference-style book covering C11.
Functional C - Pieter Hartel and Henk Muller (1997). Teaches modern practices that are invaluable for low-level programming, with concurrency and modularity in mind.
The Practice of Programming - Brian W. Kernighan and Rob Pike (1999). A very good book to accompany K&R. It uses C++ and Java too.
C Traps and Pitfalls by A. Koenig (1989). Very good, but the C style pre-dates standard C, which makes it less recommendable these days.
Some have argued for the removal of 'Traps and Pitfalls' from this list because it has trapped some people into making mistakes; others continue to argue for its inclusion. Perhaps it should be regarded as an 'expert' book because it requires moderately extensive knowledge of C to understand what's changed since it was published.
MISRA-C - industry standard published and maintained by the Motor Industry Software Reliability Association. Covers C89 and C99.
Although this isn't a book as such, many programmers recommend reading and implementing as much of it as possible. MISRA-C was originally intended as guidelines for safety-critical applications in particular, but it applies to any area of application where stable, bug-free C code is desired (who doesn't want fewer bugs?). MISRA-C is becoming the de facto standard in the whole embedded industry and is getting increasingly popular even in other programming branches. There are (at least) three publications of the standard (1998, 2004, and the current version from 2012). There is also a MISRA Compliance Guidelines document from 2016, and MISRA C:2012 Amendment 1 — Additional Security Guidelines for MISRA C:2012 (published in April 2016).
Note that some of the strictures in the MISRA rules are not appropriate to every context. For example, directive 4.12 states "Dynamic memory allocation shall not be used". This is appropriate in the embedded systems for which the MISRA rules are designed; it is not appropriate everywhere. (Compilers, for instance, generally use dynamic memory allocation for things like symbol tables, and to do without dynamic memory allocation would be difficult, if not preposterous.)
Archived lists of ACCU-reviewed books on Beginner's C (116 titles) from 2007 and Advanced C (76 titles) from 2008. Most of these don't look to be on the main site anymore, and you can't browse that by subject anyway.
Warnings
There is a list of books and tutorials to be cautious about at the ISO 9899 Wiki, which is not itself formally associated with ISO or the C standard, but contains information about the C standard (though it hails the release of ISO 9899:2011 and does not mention the release of ISO 9899:2018).
Be wary of books written by Herbert Schildt. In particular, you should stay away from C: The Complete Reference (4th Edition, 2000), known in some circles as C: The Complete Nonsense.
Also do not use the book Let Us C (16th Edition, 2017) by Yashwant Kanetkar. Many people view it as an outdated book that teaches Turbo C and has lots of obsolete, misleading and incorrect material. For example, page 137 discusses the expected output from printf("%d %d %d\n", a, ++a, a++) and does not categorize it as undefined behaviour as it should. It also consistently promotes unportable and buggy coding practices, such as using gets, %[\n]s in scanf, storing return value of getchar in a variable of type char or using fflush on stdin.
Learn C The Hard Way (2015) by Zed Shaw. A book with mixed reviews.
A critique of this book by Tim Hentenaar:
To summarize my views, which are laid out below, the author presents the material in a greatly oversimplified and misleading way, the whole corpus is a bundled mess, and some of the opinions and analyses he offers are just plain wrong. I've tried to view this book through the eyes of a novice, but unfortunately I am biased by years of experience writing code in C. It's obvious to me that either the author has a flawed understanding of C, or he's deliberately oversimplifying to the point where he's actually misleading the reader (intentionally or otherwise).
"Learn C The Hard Way" is not a book that I could recommend to someone who is both learning to program and learning C. If you're already a competent programmer in some other related language, then it represents an interesting and unusual exposition on C, though I have reservations about parts of the book. Jonathan Leffler
Outdated
Practical C Programming (3rd Edition) - Steve Oualline (1997)(Beginner)
Other contributors, not necessarily credited in the revision history, include:
Alex Lockwood,
Ben Jackson,
Bubbles,
claws,
coledot,
Dana Robinson,
Daniel Holden,
desbest,
Dervin Thunk,
dwc,
Erci Hou,
Garen,
haziz,
Johan Bezem,
Jonathan Leffler,
Joshua Partogi,
Lucas,
Lundin,
Matt K.,
mossplix,
Matthieu M.,
midor,
Nietzche-jou,
Norman Ramsey,
r3st0r3,
ridthyself,
Robert S. Barnes,
smalinux,
Steve Summit,
Tim Ring,
Tony Bai,
VMAtm

Resources