Modern C, Third Edition Covers the C23 standard (Jens Gustedt)(Z-Library)
C
No Description
15
Views
0
Downloads
0.00
Total Donations
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
Page
1
(This page has no text content)
Page
2
Praise for Modern C Great introductory material to the “new” C. This isn’t your grandfather’s C! —Hugo Durana, Microsoft Reading and working through this book is just like having an expert by your side. —Glen Sirakavit, Data Recognition The most authoritative book on C since Kernighan and Ritchie. A must-have on the shelves of all C programmers. —Manu Raghavan Sareena, Arm The definitive guide to learning modern C. —Sanchir Kartiev, Emerline
Page
3
Modern C, Third Edition Covers the C23 standard Jens Gustedt To comment go to livebook. Manning Shelter Island For more information on this and other Manning titles go to manning.com.
Page
4
copyright For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: orders@manning.com © 2025 Jens Gustedt. Jens Gustedt has released the manuscript of this work under a Creative Commons license for non-commercial use (CC BY NC). Jens Gustedt has granted to Manning Publications the exclusive commercial right to publish this work in print and electronic formats throughout the world. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher.
Page
5
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. The author and publisher have made every effort to ensure that the information in this book was correct at press time. The author and publisher do not assume and hereby disclaim any liability to any party for any loss, damage, or disruption caused by errors or omissions, whether such errors or omissions result from negligence, accident, or any other cause, or from any usage of the information herein. Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Development editor: Doug Rudder Review editor: Kishor Rit Production editor: Keri Hales
Page
6
Copy editor: Alisa Larson Proofreader: Katie Tennant Technical proofreader: Frances Buontempo Typesetter: Ammar Taha Mohamedy Cover designer: Marija Tudor ISBN 9781633437777 Printed in the United States of America
Page
7
contents preface acknowledgments about this book about the author about the cover Level 0: Encounter 1 Getting started 1.1 Imperative programming 1.2 Compiling and running 2 The principal structure of a program 2.1 Grammar 2.2 Declarations 2.3 Definitions 2.4 Statements 2.4.1 Iteration 2.4.2 Function calls 2.4.3 Function return Level 1: Acquaintance and Buckle up 3 Everything is about control
Page
8
3.1 Conditional execution 3.2 Iterations 3.3 Multiple selection 4 Expressing computations 4.1 Operands and operators 4.2 Arithmetic 4.2.1 +, -, and * 4.2.2 Division and remainder 4.3 Operators that modify objects 4.4 Boolean context 4.4.1 Comparison 4.4.2 Logic 4.5 The ternary or conditional operator 4.6 Evaluation order 5 Basic values and data 5.1 The abstract state machine 5.1.1 Values 5.1.2 Types 5.1.3 Binary representation and the abstract state machine 5.1.4 Optimization 5.2 Basic types 5.3 Specifying values 5.3.1 Complex constants 5.4 Implicit conversions 5.5 Initializers
Page
9
5.6 Named constants 5.6.1 Read-only objects 5.6.2 Enumerations 5.6.3 Macros 5.6.4 Compound literals 5.6.5 The constexpr construct 5.7 Binary representations 5.7.1 Unsigned integers 5.7.2 Bit sets and bitwise operators 5.7.3 Shift operators 5.7.4 Boolean values 5.7.5 Signed integers 5.7.6 Fixed-width integer types 5.7.7 Bit-precise integer types 5.7.8 Floating-point data 6 Derived data types 6.1 Arrays 6.1.1 Array declaration 6.1.2 Array operations 6.1.3 Array length 6.1.4 Arrays as parameters 6.1.5 Strings are special 6.2 Pointers as opaque types 6.3 Structures 6.3.1 Simple structures to access fields by name 6.3.2 Structures with fields of different types
Page
10
6.3.3 Nested structures 6.3.4 Coalescing structure fields 6.4 New names for types: Type aliases 7 Functions 7.1 Simple functions 7.2 main is special 7.3 Recursion 8 C library functions 8.1 General properties of the C library and its functions 8.1.1 Headers 8.1.2 Interfaces 8.1.3 Error checking 8.1.4 Bounds-checking interfaces 8.1.5 Platform preconditions 8.2 Integer arithmetic 8.3 Numerics 8.4 Input, output, and file manipulation 8.4.1 Unformatted text output 8.4.2 Files and streams 8.4.3 Text I/O 8.4.4 Formatted output 8.4.5 Unformatted text input 8.5 String processing and conversion 8.5.1 Portability of string processing 8.6 Time
Page
11
8.7 Runtime environment settings 8.8 Program termination and assertions Level 2: Cognition 9 Style 9.1 Formatting 9.2 Naming 9.3 Internationalization, so to speak 10 Organization and documentation 10.1 Interface documentation 10.2 Implementation 10.2.1 Macros 10.2.2 Pure functions 10.2.3 Attributes 11 Pointers 11.1 Pointer operations 11.1.1 Address-of and object-of operators 11.1.2 Pointer addition 11.1.3 Pointer subtraction and difference 11.1.4 Pointer validity 11.1.5 Null pointers 11.2 Pointers and structures 11.3 Pointers and arrays 11.3.1 Array and pointer access are the same 11.3.2 Array and pointer parameters are the same
Page
12
11.4 Function pointers 12 The C memory model 12.1 A uniform memory model 12.2 Unions 12.3 Memory and state 12.4 Pointers to unspecific objects 12.5 Explicit conversions 12.6 Effective types 12.7 Alignment 13 Storage 13.1 malloc and friends 13.1.1 A complete example with varying array size 13.1.2 Ensuring consistency of dynamic allocations 13.1.3 Flexible array members 13.2 Storage duration, lifetime, and visibility 13.2.1 Static storage duration 13.2.2 Automatic storage duration 13.3 Digression: Using objects before their definition 13.4 Initialization 13.5 Digression: A machine model 14 More involved processing and I/O 14.1 Text processing 14.2 Formatted input 14.3 Extended character sets 14.4 UTF character encodings
Page
13
14.5 Restartable text conversion 14.6 Binary streams 15 Program failure 15.1 Wrongdoings 15.1.1 Arithmetic violations 15.1.2 Invalid conversions 15.1.3 Value violations 15.1.4 Type violations 15.1.5 Access violations 15.1.6 Value misinterpretation 15.1.7 Explicit invalidation 15.2 Program state degradation 15.2.1 Unbounded recursion 15.2.2 Storage exhaustion 15.2.3 Other scarce resources 15.3 Unfortunate incidents 15.3.1 Escalating state degradation 15.3.2 Collisions and race conditions 15.3.3 Inappropriate library calls and macro invocations 15.3.4 Deadlocks 15.4 Series of unfortunate events 15.5 Dealing with failures 15.6 Error checking and cleanup Level 3: Experience 16 Performance
Page
14
16.1 Inline functions 16.2 Using restrict qualifiers 16.3 Unsequenced and reproducible attributes 16.4 Measurement and inspection 17 Function-like macros 17.1 How function-like macros work 17.2 Argument checking 17.3 Accessing the context of invocation 17.4 Variable-length argument lists 17.4.1 Variadic macros 17.4.2 A detour: Variadic functions 17.5 Default arguments 18 Type-generic programming 18.1 Inherent type-generic features in C 18.1.1 Operators 18.1.2 Default promotions and conversions 18.1.3 Macros 18.1.4 Variadic functions 18.1.5 Function pointers 18.1.6 void pointers 18.1.7 Type-generic C library functions 18.2 Generic selection 18.3 Type inference 18.3.1 The auto feature 18.3.2 The typeof feature
Page
15
18.4 Anonymous functions 19 Variations in control flow 19.1 A detailed example 19.2 Sequencing 19.3 Short jumps 19.4 Functions 19.5 Long jumps 19.6 Signal handlers 20 Threads 20.1 Simple interthread control 20.2 Race-free initialization and destruction 20.3 Thread-local data 20.4 Critical data and critical sections 20.5 Communicating through condition variables 20.6 More sophisticated thread management 20.7 Ensure liveness 21 Atomic access and memory consistency 21.1 The “happened-before” relation 21.2 C library calls that provide synchronization 21.3 Sequential consistency 21.4 Other consistency models Technical annex A. Transitional code B. C compilers
Page
16
B.1 Attributes B.2 Missing #embed B.3 Missing constexpr B.4 Missing 128-bit integer support C. C libraries C.1 Functions borrowed from POSIX or similar systems C.2 Improved UTF-8 support C.3 Bit utilities C.4 Checked integer arithmetic C.5 Formatted IO C.6 Mathematical functions C.7 A reference implementation for musl libc index
Page
17
preface As the title of this book suggests, today’s C is not the same language as the one originally designed by its creator. Right from the start, C has been in a continuous process of adjustment and improvement. Usually, early C is referred to as K&R C (Kernighan and Ritchie C) after the first book that made the language popular. Since then, it has undergone an important standardization and extension process, now driven by ISO, the International Standards Organization. This led to the publication of a series of C standards in 1989, 1999, 2011, 2018, and 2024, commonly referred to as C89, C99, C11, C17, and C23, respectively. The C standards committee puts a lot of effort into guaranteeing backward compatibility such that code written for earlier revisions of the language, say, C11, should compile to a semantically equivalent executable with a compiler that implements a newer revision. Unfortunately, this backward compatibility has had the unwanted side effect of not motivating projects that could benefit greatly from the new features to update their code base. To emphasize this progress of revisions, we indicate which standard revision introduced newer features. This edition presents a considerable rework in view of the latest revision, C23 of the C standard. A lot of new material has been added, and many expositions have been straightened out to reflect the new capabilities of the C programming language. So, in this book, we mainly refer to C23, but at the time of this writing, compilers hadn’t yet implemented this standard completely. If you want to compile the examples in this book, you will need at least a compiler that implements most of C17. For the novelties
Page
18
that C23 introduces, we provide a compatibility header and discuss how to possibly generate a suitable C compiler and C library platform on POSIX systems as a fallback in appendix B. Beware: This is not meant as a permanent tool but only as a crutch while platforms adapt. Programming has become a very important cultural and economic activity, and C remains an important element in the programming world. As in all human activities, progress in C is driven by many factors: corporate or individual interest, politics, beauty, logic, luck, ignorance, selfishness, ego, sectarianism, etc. (add your primary motivation here). Thus, the development of C has not been and cannot be ideal. It has flaws and artifacts that can only be understood within their historical and societal context. An important part of the context in which C developed was the early appearance of its sister language, C++. One common misconception is that C++ evolved from C by adding its particular features. Although this context is historically correct (C++ did evolve from a very early C), it is not particularly relevant today. In fact, C and C++ separated from a common ancestor more than 30 years ago and have evolved separately ever since. But this evolution of the two languages has not taken place in isolation; they have exchanged and adopted each other’s concepts over the years. Some new features, such as the addition of atomics and threads, have been designed in close collaboration between the C and C++ standard committees. Nevertheless, many differences remain, and generally, all that is written in this book is about C, not C++. Many of the code examples will not compile with a C++ compiler. So, we should not mix sources of both languages. In sum, C and C++ are different: don’t mix them and don’t mix them up.
Page
19
acknowledgments Special thanks go to the people who encouraged the writing of this book by providing me with constructive feedback, including colleagues and other interested readers: Cédric Bastoul, Lucas Nussbaum, Vincent Loechner, Kliment Yanev, Szabolcs Nagy, Marcin Kowalczuk, Ali Asad Lotia, Richard Palme, Yann Barsamian, Fernando Oleo, Róbert Kohányi, Jean-Michel Gorius, and Martin Uecker. Thanks also go to Manning’s staff: Jennifer Stout, Nitin Gode and Tiffany Taylor, Frances Buontempo, Doug Rudder, and the rest of the production team for their hard work in getting this book to print. Finally, thanks go to the impressive number of reviewers provided by Manning for both editions that they managed: Al Pezewski, Christian Sutton, Eli Hini, Federico Kircheis, Keith Kim, Kevin Cheung, Marcus Geselle, Patrick Wanjau Munyiri, Paul Silisteanu, Riccardo Marotti, Rich Yonts, Richard Meinsen, Srinivas Vamsi Parasa, Stephen Kitt, and Tony Holdroyd. Many others have contributed to the success of this book; my sincerest thanks go to all of you.
Page
20
about this book The C programming language has been around since the early 1970s. Since then, C has been used in an incredible number of applications. Programs and systems written in C are all around us, in personal computers, phones, cameras, set-top boxes, refrigerators, cars, mainframes, and satellites —basically in any modern device that has a programmable interface. In contrast to the ubiquitous presence of C programs and systems, good knowledge of and about C is much scarcer. Even experienced C programmers often appear to be stuck in some degree of self-inflicted ignorance about the modern evolution of the C language. A likely reason for this is that C is seen as an easy-to-learn language, allowing a programmer with little experience to quickly write or copy snippets of code that at least appear to do what they are supposed to. In a way, C fails to motivate its users to climb to higher levels of knowledge. This book is intended to change that general attitude, so it is organized into levels that reflect familiarity with the C language and programming in general. This structure may go against some habits of the book’s readers; in particular, it splits some difficult subjects (such as pointers) across levels to avoid swamping readers too early with the wrong information. We’ll explain the book’s organization in more detail shortly. Generally, although many universally applicable ideas will be presented that would also be valid for other programming languages (such as Java, Python, Ruby, C#, or C++), the book primarily addresses concepts and practices
The above is a preview of the first 20 pages. Register to read the complete e-book.
AI Reading Assistant
Whole-book reading guide from stratified index samples; jump to passages in the text
AI guide
# Modern C, Third Edition: A Comprehensive Reading Guide
## 【One-Line Pitch】
A definitive, standards-focused guide to modern C programming that covers the C23 standard, ideal for programmers who want to move beyond legacy C practices and write portable, safe, and efficient code in the contemporary language ecosystem.
## 【Book Arc】
- **Opening (~0%–10%)**: Establishes the foundation by contrasting good versus bad C programs, introducing core concepts like object and function declarations, array initialization with designated initializers, and the importance of compiler diagnostics—all framed within the C23 standard context.
- **Early (~10%–23%)**: Delves into expression evaluation, operators (including prefix/postfix increment), boolean contexts, and the critical distinction between observable and non-observable operations; introduces C23 features like binary literals and hexadecimal floating-point literals, plus the dangers of undefined behavior.
- **Early (~23%–32%)**: Explores macros and the constexpr construct introduced in C23, then transitions to functions as the primary organizational unit—covering their benefits for code reuse, readability, and compilation efficiency, alongside error-handling strategies and standard library functions.
- **Middle (~32%–48%)**: Addresses practical concerns: environment variable handling with bounds-checked functions, coding style as cultural practice (referencing Linux kernel conventions), Unicode identifier normalization, and the pitfalls of macro abuse in attributes.
- **Middle (~48%–end)**: Covers advanced topics including pointer arithmetic with ptrdiff_t, array-pointer equivalence, and transitions into sophisticated control flow mechanisms (goto, setjmp/longjmp, signal handlers), threading, and atomic operations with memory consistency models.
## 【Key Takeaways】
- **Compiler diagnostics are your first line of defense** (Opening): Modern compilers like Clang and GCC catch fundamental errors—wrong main return type, missing headers, incorrect return statements—and treating warnings as errors (-Werror) enforces standards compliance from the start.
- **Designated initializers simplify array setup** (Opening): Using syntax like `[4] = 3.E+25` allows selective initialization with unspecified elements defaulting to zero, making code more explicit and less error-prone than sequential assignment.
- **Undefined behavior is your responsibility** (Early): Programs exhibiting undefined behavior may appear correct for years before crashing unpredictably across platforms or compiler versions—understanding and avoiding UB is essential for portable code.
- **C23 introduces modern conveniences** (Early): Binary literals (0b1010), hexadecimal floating-point literals, and the constexpr construct for file-scope constant expressions represent meaningful improvements over traditional macro-based approaches.
- **Functions are the backbone of maintainable C** (Early): Beyond avoiding code duplication, functions decrease compilation times, provide clear interfaces with pre/post-conditions, and naturally support algorithmic patterns like recursion (demonstrated with Fibonacci).
- **Failure handling requires systematic strategies** (Early): C library functions use diverse error-return conventions (null pointers, EOF, negative values, errno), and checking every failure point—never sweeping errors under the carpet—is non-negotiable.
- **Coding style is cultural, not personal preference** (Middle): The Linux kernel coding style exemplifies how established projects create their own cultural spaces; adapting to existing conventions when contributing is essential for collaboration.
- **Pointer arithmetic demands proper types** (Middle): Use ptrdiff_t for pointer differences and size_t for object sizes—plain int is often insufficient—and cast pointers to void* with %p format for reliable printing.
## 【Reading Tips】
- **Skim the early compiler-error examples** (~0%–3%): The bad.c demonstration is illustrative but repetitive; grasp the three error categories (return type, missing declarations, incorrect returns) and move on.
- **Deep-read the undefined behavior sections** (~19%–23%): This is foundational material that explains why C programs fail mysteriously—understanding UB's "byzantine" nature will inform every subsequent chapter.
- **Study the error-handling tables** (~32%): The systematic categorization of failure return strategies (null pointers, special values, negative counters) is reference-worthy; bookmark these tables for practical coding.
- **Pay attention to C23-specific additions**: Binary literals, constexpr, and attribute syntax changes are highlighted throughout—note these if you're transitioning from C17 or earlier standards.
- **The advanced chapters (threads, atomics) assume prior mastery**: If you're new to concurrency, expect to re-read sections 20–21; the "happened-before" relation and memory consistency models are conceptually dense.
## 【Coverage Limits】
This guide synthesizes excerpts through approximately the middle of the book (~48%). The advanced sections on threads, atomic operations, and memory consistency models (chapters 20–21) are mentioned but not analyzed in depth due to excerpt limitations.
##
Passage locations
Excerpt 1
executable. It considers all three detected problems to be fatal errors and refuses to carry on. Consider this to be a feature. Both gave us three diagnostic...
View in text
Excerpt 2
ted as . C 0x1.7aP-13 Hexadecimal floating-point literals — These are usually used to describe floating-point values in a form that makes it easy to specify...
View in text
Excerpt 3
144, 377, 610, and 987. With the golden ratio, Equation 7.6 it can be shown that Equation 7.7 and so, asymptotically, we have Equation 7.8 So, the growth of...
View in text
Excerpt 4
e that uses it and trigger subtle bugs (subsection 10.2.1). As we saw previously, functions are the primary choice in C for modularization. Here, a particula...
View in text
Recommended for You
{{#thumbnailUrl}}
{{/thumbnailUrl}}
{{^thumbnailUrl}}
{{/thumbnailUrl}}
Loading recommended books...
Failed to load, please try again later
Tip the Site
Scan the WeChat Pay or Alipay code to tip. No login required.
WeChat Pay
Alipay