October 2026 | Glenn Coates

I’ve been working with WG14 to remove another source of undefined behaviour from C. This one comes from a simple problem: two different names can be treated as the same name.
My paper, N3911, “Slaying Some Earthly Demons: Remove UB 30”, was voted into C2y at the August 2026 WG14 meeting in Ottawa.
Only the First 31 Characters Count
Since C99, the Standard has only required an implementation to treat the first 31 characters of an external identifier (one with external linkage) as significant. For internal identifiers and macro names, the figure is 63.
C90 was stricter: only six characters of an external name had to be significant, and case could be ignored. This is why coding standards have long advised keeping external names distinct within 31 characters.
Take these two function names:
calculate_motor_controller_status()
calculate_motor_controller_state()
They share the same first 31 characters, calculate_motor_controller_stat, and only differ at the 32nd character.
If two external identifiers differ only after the significant characters, the Standard says the behaviour is undefined (Annex J.2, item 30). This means there is no telling what will happen.
Calls to either name might go to the first function, the second function, or something else entirely. The source code contains two functions, but the program may silently treat them as one.
What N3911 Changes
N3911 replaces the significant character model with three rules:
- All characters in an identifier are significant.
- Each implementation sets and documents a maximum identifier length.
- An identifier longer than that maximum requires a diagnostic.
An implementation can still impose a limit, but it can no longer silently ignore the end of an identifier.
The numbers 31 (external identifiers) and 63 (internal identifiers and macro names) remain in the Standard. They now represent the minimum identifier length an implementation must support, rather than the number of characters that must distinguish names.
The paper also removes a related unspecified behaviour (Annex J.1, item 8): how an extended source character counts towards the significant characters of an external identifier.
Why This Matters
If two names silently alias, the source code distinguishes two functions or objects, but the program does not. The wrong function could be called or the wrong object accessed, with no diagnostic at build time and no indication at run time.
In safety-critical and embedded code, that is a real hazard and can become a memory safety issue.
Until now, the only portable defence was to keep every external name within 31 characters. That can be difficult to guarantee when working with generated code.
Mainstream compilers already treat every character as significant up to large limits, and object formats such as ELF and COFF/PE store full symbol names. N3911 brings the Standard into line with that practice and with C++, which has no limit on significant characters in external identifiers.
This also helps when C and C++ code are linked into the same program.
Removing Undefined Behaviour Rather Than Working Around It
This is part of a wider effort within WG14. We spend a lot of time telling C programmers how to avoid undefined behaviour. Where we can remove it from the language, I think we should.
The C Standard charter also asks for the undefined behaviours listed in Annex J to be eliminated or reduced.
For UB 30, the fix is simple: make every character of an identifier significant, let the implementation set a documented limit, and require a diagnostic when that limit is exceeded.
Read the paper: N3911, Slaying Some Earthly Demons: Remove UB 30.