CIdentifiers & Naming Rules

Identifiers & Naming Rules

An identifier is the name you give to a variable, function, type, macro, or any other user-defined entity in a C program. C imposes a small, strict set of rules on what characters an identifier may contain, and a much larger, informal set of naming conventions that the C community has settled on over the decades for writing readable code.

Valid characters
  • Identifiers may contain letters (a-z, A-Z), digits (0-9), and the underscore (_).

  • An identifier cannot start with a digit — 2fast is invalid, but fast2 is fine.

  • No spaces, hyphens, or other punctuation are allowed inside an identifier.

  • C is case-sensitive, so total, Total, and TOTAL are three completely different identifiers.

C
int score;        /* valid */
int _hidden;      /* valid, but reserved-ish, see below */
int player2;      /* valid */
int total_count;  /* valid */

/* int 2players; */    /* INVALID: starts with a digit */
/* int player-two; */  /* INVALID: hyphen is not allowed */
/* int player two; */  /* INVALID: space is not allowed */
Reserved keywords

C reserves around 32 to 44 keywords (depending on the standard version) for the language itself, such as int, return, for, while, struct, and static. These words have special meaning to the compiler and cannot be used as identifiers for your own variables or functions.

C
/* int return = 5; */   /* INVALID: 'return' is a reserved keyword */
int result = 5;         /* valid alternative */
Naming conventions

The C standard itself has no opinion on style beyond the character rules above, but decades of shared practice have produced strong conventions that most C codebases follow.

Convention

Typical use

Example

snake_case

Variables and function names (dominant in C)

total_score, read_file()

ALL_CAPS

Macro constants defined with #define

MAX_BUFFER_SIZE

PascalCase

Occasionally for type/struct names in some codebases

PlayerState

Leading underscore

Reserved for the implementation — avoid in your own code

_internal_flag

snake_case is the norm
Unlike Java or JavaScript, which favor camelCase, the dominant convention across the C standard library and most open-source C projects (the Linux kernel, glibc, PostgreSQL) is snake_case: lowercase words separated by underscores.
Identifiers starting with underscore are reserved
Don't start your own identifiers with an underscore
The C standard reserves certain identifier patterns for the compiler and standard library implementation: any identifier beginning with two underscores (`__foo`), or a single underscore followed by an uppercase letter (`_Foo`), is reserved everywhere. At file scope, an identifier starting with a single underscore (`_foo`) is also reserved. Using these patterns for your own variables or functions technically invokes undefined behavior and can silently collide with names the compiler or a system header already uses.

C
/* Avoid these in your own code: */
int __count;   /* reserved: leading double underscore */
int _Value;    /* reserved: underscore + uppercase letter */

/* Prefer plain, descriptive names instead: */
int count;
int value;
  • Identifiers: letters, digits, and underscore only; cannot start with a digit.

  • C is case-sensitive — Data and data are different names.

  • Reserved keywords (int, for, return, etc.) cannot be used as identifiers.

  • Follow snake_case for variables/functions and ALL_CAPS for macro constants.

  • Never start your own identifiers with an underscore — that space belongs to the implementation.