Keywords in C
Learn all 32 reserved words in C that have special meaning. These words are reserved by C and cannot be used as variable names.
Track Your Progress
Sign in to save your learning progress
What You Will Learn
- ✓Know all 32 C keywords
- ✓Understand why keywords cannot be used as names
- ✓Recognize keywords by category (data types, control, storage)
01What are Keywords?
Definition
Keywords (also called reserved words) are predefined words in C that have special meanings. They are part of C's syntax and cannot be used as identifiers (variable names, function names, etc.).
Invalid
int int = 5; // ERROR!float return; // ERROR!char if = 'a'; // ERROR!✓Valid
int number = 5; // OKfloat result; // OKchar initial = 'a'; // OKKey Points
- • C has 32 keywords (C89/C90 standard)
- • All keywords are in lowercase
- • Keywords are case-sensitive (if ≠ IF)
- • Cannot be used as variable/function names
02All 32 Keywords in C
Complete List of C Keywords (32 Total)
Note: Newer C Standards Added More
C99: inline, restrict, _Bool, _Complex, _Imaginary
C11: _Alignas, _Alignof, _Atomic, _Generic, _Noreturn, _Static_assert, _Thread_local
C23: true, false, nullptr, constexpr, typeof, static_assert, thread_local, alignas, alignof, bool
02bC99 Keywords (5 New)
The C99 standard (1999) introduced these new keywords:
| Keyword | Purpose | Detailed Explanation |
|---|---|---|
| inline | Inline function hint | Suggests to the compiler to insert the function code directly at call site for better performance. Reduces function call overhead. |
| restrict | Pointer aliasing hint | Tells compiler that a pointer is the only way to access the object it points to. Enables aggressive optimizations. |
| _Bool | Boolean type | Native boolean type that can hold 0 (false) or 1 (true). Use <stdbool.h> for bool, true, false macros. |
| _Complex | Complex numbers | For complex number arithmetic. Use float _Complex, double _Complex. Include <complex.h> for complex macro. |
| _Imaginary | Imaginary numbers | For pure imaginary number types. Rarely implemented by compilers. Optional in C99. |
1#include <stdio.h>2#include <stdbool.h> // For bool, true, false3#include <complex.h> // For complex numbers45// inline function - compiler may insert code directly6inline int square(int x) {7 return x * x;8}910// restrict - promise this is the only pointer to this memory11void copy_array(int *restrict dest, const int *restrict src, int n) {12 for (int i = 0; i < n; i++) {13 dest[i] = src[i];14 }15}1617int main() {18 // _Bool / bool usage19 _Bool flag1 = 1; // Raw C99 boolean20 bool flag2 = true; // With stdbool.h (preferred)21 22 printf("flag1: %d, flag2: %d\n", flag1, flag2);23 printf("square(5): %d\n", square(5));24 25 // Complex numbers26 double _Complex z = 3.0 + 4.0 * I;27 printf("Complex: %.1f + %.1fi\n", creal(z), cimag(z));28 29 return 0;30}02cC11 Keywords (7 New)
The C11 standard (2011) added powerful new features:
| Keyword | Macro Form | Detailed Explanation |
|---|---|---|
| _Alignas | alignas | Specifies memory alignment for a variable. _Alignas(16) int x; aligns x to 16-byte boundary. |
| _Alignof | alignof | Returns the alignment requirement of a type. Like sizeof but for alignment. |
| _Atomic | atomic_* | Declares atomic variables for lock-free thread-safe operations. Essential for multi-threaded programs. |
| _Generic | - | Type-generic selection. Enables function overloading by selecting code based on expression type at compile time. |
| _Noreturn | noreturn | Marks functions that never return (like exit(), abort()). Helps compiler optimize. |
| _Static_assert | static_assert | Compile-time assertion. Causes compilation error if condition is false. Great for catching errors early. |
| _Thread_local | thread_local | Each thread gets its own copy of the variable. Essential for thread-safe global state. |
1#include <stdio.h>2#include <stdalign.h> // For alignas, alignof3#include <stdnoreturn.h> // For noreturn4#include <stdatomic.h> // For atomic types56// Compile-time assertion7_Static_assert(sizeof(int) >= 4, "int must be at least 4 bytes");89// Function that never returns10noreturn void fatal_error(const char *msg) {11 printf("FATAL: %s\n", msg);12 exit(1);13}1415// Type-generic macro using _Generic16#define print_type(x) _Generic((x), \17 int: "int", \18 float: "float", \19 double: "double", \20 char*: "string", \21 default: "unknown")2223int main() {24 // Memory alignment25 alignas(16) int aligned_var = 42;26 printf("Alignment of int: %zu\n", alignof(int));27 printf("Alignment of aligned_var: %zu\n", alignof(aligned_var));28 29 // Atomic variable for thread safety30 atomic_int counter = 0;31 atomic_fetch_add(&counter, 1); // Thread-safe increment32 printf("Counter: %d\n", counter);33 34 // Type-generic selection35 printf("Type of 42: %s\n", print_type(42));36 printf("Type of 3.14: %s\n", print_type(3.14));37 38 // Thread-local (each thread has own copy)39 _Thread_local static int per_thread_counter = 0;40 per_thread_counter++;41 42 return 0;43}_Generic is Powerful!
_Generic enables "function overloading" in C by selecting different code paths based on type. The tgmath.h header uses this to make sin(), cos(), etc. work with float, double, and complex types!
02dC23 Keywords (Latest Standard) 🆕
The C23 standard (2023/2024) brings major improvements and new keywords:
| Keyword | Status | Detailed Explanation |
|---|---|---|
| true | Now a keyword! | No longer a macro - true is a proper keyword. Value is 1. |
| false | Now a keyword! | No longer a macro - false is a proper keyword. Value is 0. |
| bool | Now a keyword! | Boolean type is now a native keyword. No need for <stdbool.h> anymore. |
| nullptr | New! | Type-safe null pointer constant. Better than NULL macro. Has type nullptr_t. |
| constexpr | New! | Compile-time constant expressions. Like const but evaluated at compile time. From C++! |
| typeof | Standardized! | Gets the type of an expression. Was a GCC extension, now standard. typeof(x) y; makes y same type as x. |
| typeof_unqual | New! | Like typeof but removes const/volatile qualifiers. typeof_unqual(const int) → int. |
| static_assert | Now a keyword! | Was _Static_assert with macro. Now a proper keyword. Message is optional in C23. |
| alignas | Now a keyword! | Was _Alignas with macro. Now a proper keyword. |
| alignof | Now a keyword! | Was _Alignof with macro. Now a proper keyword. |
| thread_local | Now a keyword! | Was _Thread_local with macro. Now a proper keyword. |
| _BitInt(N) | New! | Arbitrary-width integers! _BitInt(128) creates a 128-bit integer. N can be any positive integer. |
| _Decimal32/64/128 | New! | Decimal floating-point types for precise financial calculations. No binary rounding errors! |
1// C23 Features - Use with -std=c23 compiler flag2#include <stdio.h>3// No need for <stdbool.h> in C23!45int main() {6 // bool, true, false are now keywords7 bool is_valid = true;8 bool is_empty = false;9 10 // nullptr - type-safe null pointer11 int *ptr = nullptr; // Better than NULL12 if (ptr == nullptr) {13 printf("Pointer is null\n");14 }15 16 // constexpr - compile-time constants17 constexpr int BUFFER_SIZE = 1024;18 constexpr double PI = 3.14159265359;19 20 // typeof - get type of expression21 int x = 42;22 typeof(x) y = 100; // y is also int23 typeof(x + 1.0) z = 3.14; // z is double24 25 // typeof_unqual - remove const/volatile26 const int ci = 10;27 typeof_unqual(ci) mutable_copy = ci; // mutable_copy is int, not const int28 mutable_copy = 20; // OK, not const!29 30 // static_assert - no message required in C2331 static_assert(sizeof(int) >= 4); // Message optional!32 static_assert(BUFFER_SIZE > 0, "Buffer must be positive");33 34 // _BitInt - arbitrary width integers35 _BitInt(128) big_number = 12345678901234567890wb;36 unsigned _BitInt(256) huge = 0;37 38 // Decimal floating point (if supported)39 // _Decimal64 price = 19.99DD; // No binary rounding errors!40 41 printf("is_valid: %d\n", is_valid);42 printf("BUFFER_SIZE: %d\n", BUFFER_SIZE);43 44 return 0;45}✓C23 Simplifications
- • No more
#include <stdbool.h> - •
nullptrreplacesNULL - • Cleaner names:
alignasvs_Alignas - • Optional message in
static_assert
🆕 C23 New Features
- •
constexprfor compile-time eval - •
typeofstandardized - •
_BitInt(N)arbitrary integers - • Decimal floating-point types
Compiler Support
C23 features require a recent compiler with -std=c23 or -std=c2x flag. GCC 13+, Clang 16+ have partial support. Check your compiler documentation for availability.
03Data Type Keywords
These keywords define the type of data a variable can hold.
int
4 bytes • Whole numbersint age = 25;int count = -10;int sum = age + count; // sum = 15float
4 bytesfloat price = 19.99f; // f suffix!float temp = -5.5f;double
8 bytes • More precisedouble pi = 3.14159265359;double result = pi * 2;char
1 byte • Single characterchar grade = 'A'; // Use single quotes!char newline = '\n'; // Special characterchar digit = '5'; // Character, not number 5void
"No type"void sayHello(void) { // Returns nothing, takes nothing printf("Hello!\n");}void *ptr; // Generic pointer (any type)short
2 bytes • Small rangeshort small = 32000;short year = 2024;long
4-8 bytes • Large rangelong population = 8000000000L;long long huge = 9223372036854775807LL;signed
Negative + Positivesigned int temp = -10; // Can be negativeint x = -5; // signed by defaultunsigned
Only 0 and Positiveunsigned int count = 0; // 0 to 4 billionunsigned char byte = 255; // 0 to 25504Control Flow Keywords
These keywords control the flow of execution in your program.
Decision Making
int age = 18;if (age >= 18) { printf("Adult\n");} else { printf("Minor\n");}// Output: Adultint day = 3;switch (day) { case 1: printf("Monday"); break; case 2: printf("Tuesday"); break; case 3: printf("Wednesday"); break; default: printf("Other day");}// Output: WednesdayLoops
for (int i = 0; i < 3; i++) { printf("%d ", i);}// Output: 0 1 2int x = 3;while (x > 0) { printf("%d ", x); x--;}// Output: 3 2 1int x = 0;do { printf("Runs once!\n");} while (x > 0); // Condition is false, but runs oncefor (int i = 0; i < 10; i++) { if (i == 3) break; // Stop! printf("%d ", i);}// Output: 0 1 2for (int i = 0; i < 5; i++) { if (i == 2) continue; // Skip 2 printf("%d ", i);}// Output: 0 1 3 4int x = 0;start: printf("%d ", x); x++; if (x < 3) goto start; // Jump back// Output: 0 1 2goto makes code hard to read. Use loops instead!
int add(int a, int b) { return a + b; // Exit and return result}int main() { int sum = add(5, 3); // sum = 8 return 0; // Exit program successfully}05Storage Class Keywords
These keywords define where a variable is stored and how long it exists.
void func() { auto int x = 5; // Same as just: int x = 5; int y = 10; // auto is implied} // x and y are destroyed herevoid counter() { static int count = 0; // Only initialized ONCE! count++; printf("Called %d times\n", count);}int main() { counter(); // Called 1 times counter(); // Called 2 times counter(); // Called 3 times}file1.c
int counter = 0; // Definitionfile2.c
extern int counter; // Declarationcounter++; // Uses counter from file1.cregister int i; // Hint: store in CPU registerfor (i = 0; i < 1000000; i++) { // Fast loop counter (historically)}// Modern compilers ignore this - they optimize better!Obsolete. Let the compiler optimize.
06User-Defined Type Keywords
Create your own custom data types.
struct Person { char name[50]; int age;};struct Person john = {"John", 25};printf("%s is %d\n", john.name, john.age);// Output: John is 25enum Day { MON, TUE, WED, THU, FRI }; // 0, 1, 2, 3, 4enum Day today = WED;if (today == WED) { printf("It's Wednesday!\n");}typedef unsigned int uint;typedef char* String;uint count = 100; // Same as: unsigned int countString name = "Hi"; // Same as: char* nameunion Data { int i; float f;}; // Size = largest member (4 bytes)union Data d;d.i = 42; // Store as intd.f = 3.14f; // Overwrites! Same memory location07Other Important Keywords
These keywords serve special purposes.
printf("int: %zu bytes\n", sizeof(int)); // 4printf("char: %zu bytes\n", sizeof(char)); // 1printf("double: %zu bytes\n", sizeof(double)); // 8int arr[10];printf("Array: %zu bytes\n", sizeof(arr)); // 40const int MAX = 100;const double PI = 3.14159;// MAX = 200; // ERROR! Can't modify constprintf("PI = %f\n", PI);volatile int sensor_value; // Hardware might change this!// Compiler won't optimize away readswhile (sensor_value == 0) { // Keep checking - value can change externally}Used for hardware registers, signal handlers, and multi-threaded code.
08Keywords by Category
Data Types (9)
Control Flow (12)
Storage Classes (4)
User-Defined Types (4)
Other Keywords (3)
!Code Pitfalls: Common Mistakes & What to Watch For
These are the most common mistakes that trip up beginners. Study them carefully to avoid hours of debugging!
Using Keywords as Variable Names
int for = 5; // ERROR: 'for' is a keywordWrong Case
IF (x > 5) // ERROR: should be lowercase 'if'Misspelling Keywords
swicth (x) // ERROR: should be 'switch'10Total Keywords by C Standard
Keyword Evolution
Watch Out When Copying Code!
Key Takeaways
- •C89 has 32 keywords, modern C23 has ~63 keywords
- •All keywords are lowercase (except _Underscore prefixed ones)
- •Keywords cannot be used as variable/function names
- •Categories: Data Types, Control Flow, Storage Classes, User Types, Type Qualifiers
- •C23 promotes many macros to proper keywords: bool, true, false, nullptr, alignas, alignof, static_assert
- •Use
-std=c99,-std=c11, or-std=c23to enable newer keywords
Best Practice
Start with learning the 32 C89 keywords - they're used everywhere and work with all compilers. Then learn C99/C11 features as needed. C23 is cutting-edge and requires the latest compilers.
Test Your Knowledge
Related Tutorials
Identifiers in C
Learn the rules for naming things in C - variables, functions, and more. Know what names are valid, and follow naming conventions that professionals use.
Data Types & Variables
Learn to store different kinds of data: numbers (int), decimals (float), and characters (char). Understand how much memory each type uses.
Input/Output in C
Make your programs interactive! Learn to display output with printf() and read user input with scanf(). Essential for every C program.
Have Feedback?
Found something missing or have ideas to improve this tutorial? Let us know on GitHub!