C23 (C 표준 개정판)

**C23**, 공식적으로 **ISO/IEC 9899:2024**는 C17 (표준 ISO/IEC 9899:2018)을 대체하는 C 프로그래밍 언어의 현재 개방형 표준이다. 2016년에 C2x로 비공식적으로 시작되었으며, 2024년 10월 31일에 발행되었다. 발행된 문서와 가장 유사한 무료 초안은 N3220 문서이다. (아래 사용 가능한 텍스트 참조) C2x 초안을 위한 첫 WG14 회의는 2019년 10월에 개최되었고, 2020년에는 코로나19 범유행으로 인해 가상 원격 회의가 개최되었고, 2024년까지 다양한 전화 회의가 계속되었다.

C23에서 __STDC_VERSION__의 값은 201710L에서 202311L로 변경된다. "C17" 및 "C23"이라는 일반적인 이름은 ISO 표준 식별자(9899:2018 및 9899:2024)의 연도보다는 최종 채택 전에 고정된 이러한 값을 반영한다.

## 기능
C23의 최신 작업 초안에 통합된 변경 사항은 다음과 같다.

### 표준 라이브러리

#### 새로운 함수
* 최적화 여부에 관계없이 메모리 저장이 항상 수행되어야 하는 민감한 데이터를 지우기 위해 `<[[string.h]]>`에 `memset_explicit()` 함수를 추가한다.
* POSIX 및 SVID C 확장과 유사하게 문자열을 효율적으로 연결하기 위해 `<string.h>`에 `[[memccpy]]()` 함수를 추가한다.
* POSIX 및 SVID C 확장과 유사하게 문자열의 복사본을 할당하기 위해 `<string.h>`에 `[[strdup]]()` 및 `strndup()` 함수를 추가한다.
* 포인터의 바이트 정렬을 확인하기 위해 `<[[stdlib.h]]>`에 `memalignment()` 함수를 추가한다.
* 새로운 헤더 `<[[stdbit.h]]>`에 비트 유틸리티 함수/매크로/유형을 추가하여 많은 정수 유형을 검사한다. 모두 레거시 코드 및 타사 라이브러리와의 충돌을 최소화하기 위해 `stdc_`로 시작한다.
** 다음에서 `*`를 `uc`, `us`, `ui`, `ul`, `ull`로 대체하여 다섯 가지 함수 이름을 만들거나, 유형 일반 매크로의 경우 공백으로 대체한다.
** 값의 1 또는 0 비트 수를 세는 `stdc_count_ones*()` 및 `stdc_count_zeros*()`를 추가한다.
** 값의 선행 1 또는 0 비트 수를 세는 `stdc_leading_ones*()` 및 `stdc_leading_zeros*()`를 추가한다.
** 값의 후행 1 또는 0 비트 수를 세는 `stdc_trailing_ones*()` 및 `stdc_trailing_zeros*()`를 추가한다.
** 값에서 첫 번째 선행 비트가 1 또는 0인 것을 찾는 `stdc_first_leading_one*()` 및 `stdc_first_leading_zero*()`를 추가한다.
** 값에서 첫 번째 후행 비트가 1 또는 0인 것을 찾는 `stdc_first_trailing_one*()` 및 `stdc_first_trailing_zero*()`를 추가한다.
** 값이 정확히 2의 거듭제곱인지 확인하는 `stdc_has_single_bit*()`를 추가한다 (단 하나의 1 비트만 있는 경우에만 true 반환).
** 값보다 크지 않은 가장 큰 정수 2의 거듭제곱을 결정하는 `stdc_bit_floor*()`를 추가한다.
** 값보다 작지 않은 가장 작은 정수 2의 거듭제곱을 결정하는 `stdc_bit_ceil*()`을 추가한다.
** 값을 나타내는 데 필요한 비트 수를 결정하는 `stdc_bit_width*()`를 추가한다.
* glibc 및 musl 라이브러리의 함수와 유사하게 시간 구조를 달력 시간 값으로 변환하는 `<[[time.h]]>`에 `timegm()` 함수를 추가한다.
* \pi x 단위로 작동하는 삼각 함수 및 `exp10`과 같은 IEEE 754-2019 권장 사항을 기반으로 하는 새로운 `<[[math.h]]>` 함수.

#### 기존 함수
* `printf()` 함수군에 `%b` 이진 변환 지정자를 추가한다.
* `scanf()` 함수군에 `%b` 이진 변환 지정자를 추가한다.
* `strtol()` 및 `wcstol()` 함수군에 `0b` 및 `0B` 이진 변환 지원을 추가한다.
* `[[bsearch]]()`, `[[bsearch|bsearch_s]]()`, `[[memchr]]()`, `[[strchr]]()`, `[[strpbrk]]()`, `[[strrchr]]()`, `[[strstr]]()`, 그리고 그들의 와이드 counterpart인 `[[wmemchr]]()`, `[[wcschr]]()`, `[[wcspbrk]]()`, `[[wcsrchr]]()`, `[[wcsstr]]()` 함수가 전달된 경우 const 한정된 객체를 반환하도록 한다.

### 전처리기
*  및  지시자를 추가한다. 이는 기본적으로  및 와 동일하다. 두 지시자 모두  표준 및 GCC 12에 추가되었다.
* 이진 리소스 포함을 위한  지시자와 전처리기 지시자를 통해 리소스의 가용성을 확인할 수 있는 를 추가한다.
* 진단을 위한  지시자를 추가한다.
* 전처리기 지시자를 통해 헤더의 가용성을 확인할 수 있는 를 추가한다.
* 전처리기 지시자를 통해 속성의 가용성을 확인할 수 있는 를 추가한다. (새로운 속성 기능에 대한 " 호환성" 그룹 참조)
* 포함하는 매크로에 가변 인수가 전달된 경우에만 해당 인수로 확장되는 가변 매크로용  함수 매크로를 추가한다.

### 유형
* null 포인터 유형인 를 추가한다.
* 비트 정밀 정수를 위한  및  유형을 추가한다. 최대 비트 폭을 위한  매크로를 추가한다.
* 확인된 정수 연산을 위한 `ckd_add()`, `ckd_sub()`, `ckd_mul()` 매크로를 추가한다.
* 가변 수정 유형 (스택에 할당되는 자동 변수인 VLA는 제외)은 필수 기능이 된다.
* 배열과 함께 `[[Const_(computer_programming)|const]]`를 사용하는 것에 대한 더 나은 지원.
* `[[Typeof]](...)` 연산자의 표준화.
*  키워드의 의미가 변경되어 타입 추론을 유발하는 동시에, 유형과 함께 사용될 경우 기존의 저장 클래스 지정자로서의 의미도 유지한다. C++와 달리 C23은 객체 정의에만 타입 추론을 허용한다(함수 반환 유형 또는 함수 매개변수 유형은 추론하지 않음).
* 구조체, 공용체, 열거형의 호환성 규칙이 변경되어 동일한 태그를 가진 호환 유형의 재선언을 허용한다.
* 정밀 너비 정수는 이제 를 초과할 수 있다(N2888).

### 상수
* `nullptr_t` 유형에 대한  상수를 추가한다.
*  및  유형에 대한 `wb` 및 `uwb` 정수 리터럴 접미사를 추가한다. 예를 들어, 는 `unsigned _BitInt(3)`을 생성하고, 는 세 개의 값 비트와 하나의 부호 비트를 가진 `signed _BitInt(4)`를 생성한다.
* 이진 리터럴 상수 접두사 `0b` 및 `0B`를 추가한다. 예를 들어,  (0xAA와 동일).
* 리터럴 상수에 `'` 숫자 구분자를 추가한다. 예를 들어,  (0xFEDCBA98와 동일),  (299792458와 동일),  (1.414213562와 동일).
* `[[열거형|enum]]`의 기본 유형을 지정하는 기능을 추가한다.
* 고정된 기본 유형이 없는 이 로 표현할 수 없는 값을 저장할 수 있도록 허용한다.

### 키워드
*  및  키워드를 추가한다.
* , , , ,  키워드를 추가한다. 이전에 정의된 키워드들은 대체 철자가 된다: , , , , .
*  키워드 추가 ("유형" 그룹 참조)
*  및  키워드 추가 ("유형" 그룹 참조)
*  키워드 추가 ("상수" 그룹 참조)
*  키워드 추가 ("기타" 그룹 참조)
* (선택적) 십진 부동소수점 연산을 위한 , ,  키워드 추가 ("기타" 그룹 참조)

### 구문
* 레이블은 선언 앞에 올 수 있으며 복합 문의 끝에도 올 수 있다.
* 함수 정의에서 이름 없는 매개변수.
* `{}`를 사용한 0 초기화 (VLA 초기화 포함).
* 가변 인자 함수는 더 이상 줄임표 앞에 이름 있는 인수를 필요로 하지 않으며,  매크로는 더 이상 두 번째 인수를 필요로 하지 않으며, 첫 번째 인수 이후의 인수는 평가하지 않는다.
* 이중 대괄호 를 사용하는 C++11 스타일 속성 구문을 추가한다. 아래 나열된 C++11 속성 외에 새로운 속성을 추가한다.
** ``는 함수가 매개변수에만 기반하여 반복 가능한 출력을 생성하는 경우 컴파일러 최적화를 허용한다.
** ``, ``와 유사하지만, 호출 순서도 중요한 함수에 해당한다.
* C++17과의 호환성을 위해 단일 인수 `[[Assert.h#static assert|_Static_assert]]`를 추가한다.
* 프로토타입에 인수가 나열되지 않은 함수(예: `void foo()`)는 인수를 취하지 않는 것으로 이해된다 (K&R 함수 선언 제거 참조).

### C++ 호환성
* 레이블이 선언 앞에 오는 것, 이름 없는 함수 인수, `{}`를 사용한 0 초기화, 이름 있는 인수 없는 가변 인자 함수, C++11 스타일 속성, `[[Assert.h#static assert|_Static_assert]]`와 같은 다양한 구문 변경 사항은 C++와의 호환성을 향상시킨다 (구문 참조). 복합 문의 끝에 오는 레이블의 경우 C++23에 해당 변경 사항이 적용되었다.
* C++ 스타일 속성을 추가한다 (구문 참조). C++11과의 호환성을 위해 , , , , 그리고  속성을 추가한 다음, C11에서 도입된 , , 헤더 `<stdnoreturn.h>` 기능을 더 이상 사용하지 않는다. C++23과의 호환성을 위해 중복 속성이 허용된다. 모든 표준 속성은 이중 밑줄로 둘러쌀 수도 있다 (예: 는 와 동일하다).
* C++17과의 호환성을 위해 문자 리터럴에 `u8` 접두사를 추가하여 UTF-8 인코딩을 나타낸다.
* C++23과의 호환성을 위해  및  전처리기 지시자를 추가한다. ("전처리기" 그룹 참조)

### 기타 기능
* 현재 IEEE 754 표준의 부동소수점 연산 버전인 ISO/IEC 60559:2020을 확장된 이진 부동소수점 연산 및 (선택적) 십진 부동소수점 연산으로 지원한다.

* C++의 해당 기능과 달리 객체에 대한 `[[constexpr]]` 지정자는 함수에는 적용되지 않는다.
* UTF-8로 인코딩된 데이터를 저장하기 위한  유형을 추가하고 u8 문자 상수 및 문자열 리터럴의 유형을 로 변경한다. 또한, 좁은 멀티바이트 문자를 UTF-8 인코딩으로 변환하고 UTF-8에서 좁은 멀티바이트 문자 표현으로 단일 코드 포인트를 변환하는 함수인 `mbrtoc8()` 및 `c8rtomb()`를 추가한다.
* 명시적으로 지정하지 않는 한 모든  문자열 및 리터럴은 UTF-16으로 인코딩되어야 하고, 모든  문자열 및 리터럴은 UTF-32로 인코딩되어야 함을 명확히 한다.
* 복합 리터럴 정의에 저장 클래스 지정자를 허용한다.

## 더 이상 사용되지 않는 기능
일부 오래된 기능은 C23의 작업 초안에서 제거되거나 더 이상 사용되지 않는다.
:* 삼중자를 제거한다.
:* K&R 함수 정의/선언 (함수 인수에 대한 정보 없음)을 제거한다.
:* 2의 보수 이외의 부호 있는 정수 표현을 제거한다. 2의 보수 부호 있는 정수 표현이 요구될 것이다.
:* `<float.h>`의  매크로는 더 이상 사용되지 않는 기능이다.

## 컴파일러 지원
다음 컴파일러는 이 표준을 지원하기 위한 실험적 컴파일러 플래그를 구현한다:

* GCC 9,
* Clang 9.0,
* Pelles C 11.00

## 사용 가능한 텍스트

다른 C 표준판과 마찬가지로, 표준의 공식 ISO 텍스트는 무료로 제공되지 않는다.

공개된 C23 이전의 최신 작업 초안은 2023년 4월 1일자 N3096이었다. 이 초안 이후 몇 달 동안 수백 가지 변경 사항이 이루어져 2023년 7월 9일자 작업 초안 N3149와 2024년 2월 22일자 공식 초안 표준 N3219가 생성되었다. 이 후자의 초안들은 공개되지 않았다.

초안 표준 N3219가 발표된 같은 날, 새로운 작업 초안 N3220이 공개되었다. 이 문서는 공식적으로 표준의 미래 버전 "C2Y"의 초안으로 설명되지만, 동봉된 "편집자 보고서"는 N3220이 C23 초안 표준 N3219와 부록 K의 한 각주만 다르다고 명시한다.

## 같이 보기

* C++23, C++20, C++17, C++14, C++11, C++03, C++98, C++ 프로그래밍 언어 표준 버전
* C와 C++의 호환성

## 각주

## 더 읽어보기
* N3096 (C23 이전의 마지막 무료 이용 가능한 작업 초안); WG14; 2023년 4월. (무료 다운로드)
* N3149 (C23 표준 작업 초안); WG14; 2023년 7월. (공개 이용 불가)
* N3219 (ISO/IEC 9899:2023 DIS 초안); WG14; 2024년 2월. (ISO 초안은 이용 가능하지만 무료는 아님)
* ISO/IEC 9899:2024 (공식 C23 표준); ISO; 2024. (2024년 출시 예정)
* N3220 (C23 이후 첫 번째 작업 초안; 초안 표준 N3219와 한 각주만 다름); WG14; 2024년 2월. (무료 다운로드)

## 외부 링크
* C 언어 WG14 (Working Group 14)
:* WG14 문서 저장소
:* WG14 회의 - 의제 및 회의록
:* WG14 헌장: C2x 헌장, C23 헌장, C23 헌장 해석, C 표준 헌장

분류:프로그래밍 언어 표준
분류:C 프로그래밍 언어