Issue 1024: Redeclaration of standard library typedefs

Authors: Jay Ghiron
Date: 2026-02-25
Submitted against: C23
Status: Open

Since C11, it has been valid to redeclare typedefs with an equivalent type. For example:

typedef int T;
typedef int T;

However, this is never stated as being valid for standard library types:

#include<stddef.h>
typedef typeof(sizeof(0))size_t;

Since size_t is a reserved identifier, it is not valid to provide a macro definition or another definition at file scope. But it seems unnecessary to forbid this, it would be impossible to make this invalid in an implementation of the standard library using normal C typedefs. If the order were swapped:

typedef typeof(sizeof(0))size_t;
#include<stddef.h>

Then it would be possible for a normal C header to forbid this, for example:

#ifndef __SIZE_T_DEFINED__/* or another name reserved to the implementation */
#define __SIZE_T_DEFINED__
static_assert(_Generic((void(*)(int(size_t)))0,void(*)(int):1,default:0));
typedef typeof(sizeof(0))size_t;
#endif

Though it would not make any sense for this to be done. A motivating example to allow this is so that a header can provide size_t without including everything else in one of the standard headers that provides size_t. The same would also be possible for ptrdiff_t, wchar_t, errno_t, rsize_t, char8_t, char16_t, char32_t, nullptr_t, constraint_handler_t, tss_dtor_t, thrd_start_t, and many of the types beginning with atomic_.

Suggested correction

Insert at the end of C23 7.1.2 paragraph 1:

Declarations of types described here, in Annex H, or in Annex K, shall not include type qualifiers, unless explicitly stated otherwise. For types in the ordinary name space described here, in Annex H, or in Annex K, it is permissible to declare the identifier as a typedef name at file scope with an equivalent type, including declarations which occur before any standard header defines the identifier.

Note: The wording "ordinary name space" is used to avoid including the types struct timespec, struct tm, and struct lconv.

Note: There seems to be some irregularity in the standard when saying an identifier has file scope, it uses "has file scope" (or equivalently "have file scope"), "at file scope", "in file scope", and "with file scope".

Modify C23 7.1.2 paragraph 5:

If used, a header shall be included outside of any external declaration or definition, and it shall first be included before the first reference to any of the functions or objects it declares, or to any of the types or macros it defines, except for functions or types declared or defined respectively before the header is included.

Note: The text seems to currently forbid declaring a library function, using it, then including the header. Even though it would be valid to declare a library function and use it without including the header.