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.


Comment from Issues list maintainer on 2026-08-21:

This issue was discussed at the August 2026 (Ottawa) meeting of WG14. Joseph Myers took an action item to propose wording to disallow such redeclarations (making them undefined behavior if a header with the standard declaration is included in the same translation unit, not requiring or expecting any implementations to change), in accordance with the view that declaring library functions other than through including the relevant header is also a legacy feature and in general declaring standard library features in user code is to be discouraged.


Comment from Issues list maintainer on 2026-08-25:

In reflector message 37700, Joseph Myers proposed a response that confirms there is existing undefined behavior for such redeclarations and that this reflects the committee's intent.

Suggested response

C23 6.4.3.1 (Identifiers: General) specifies that:

If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), the behavior is undefined.

C23 7.1.3 (Reserved identifiers) says:

C23 7.1.4 (Use of library functions) does not provide any exceptions relevant to typedef names.

Thus, it is undefined behavior for an application to declare a standard library typedef name with file scope in any translation unit that includes the associated header. The committee does not wish to allow such redeclarations.