C 언어, 이렇게 쓰면 더 안전하고 효율적입니다!

by DD
4개월 전
조회수 40

C23 표준을 기반으로, 타입 정의(Typedef), 문자열 구조체(String Struct), 튜플(Tuple) 등 현대적인 C 스타일 가이드 제시

'파싱(Parsing) 우선, 검증(Validation) 지양' 철학을 바탕으로, 타입 시스템을 활용한 안전한 API 설계 강조

결과 반환(Returning Results)을 위한 구조체 활용, 오류 처리의 효율성을 높이는 방법 소개

동적 메모리 관리(Dynamic Memory Management)에 대한 개인적인 경험과, Rust 또는 C#과 같은 다른 언어 사용을 권장

C23 표준 채택과 타입 정의

작성자는 C23 표준을 기반으로 개발하며, u8, i16, u32 등과 같은 타입 정의(Typedef)를 사용하여 코드의 가독성을 높인다. 특히, `CHAR_BIT != 8`인 환경을 명시적으로 처리하여 이식성을 확보한다. 이러한 접근 방식은 코드의 명확성을 높이고, 특정 플랫폼에 대한 의존성을 줄여 유지보수성을 향상시키는 데 기여한다.

안전한 문자열 처리를 위한 구조체 활용

작성자는 C 언어의 null-terminated string의 단점을 보완하기 위해 길이(Length) + 데이터(Data) 방식의 문자열 구조체를 사용한다. 이 구조체는 null terminator를 포함하는 `data`와 null terminator를 제외한 `len`을 포함하여, 메모리 복사 시 안전성을 확보한다. 이러한 방식은 버퍼 오버플로우(Buffer Overflow)와 같은 잠재적 위험을 줄이고, 문자열 조작의 안정성을 높인다.

파싱 우선, 검증 지양 철학

작성자는 '파싱(Parsing) 우선, 검증(Validation) 지양' 철학을 C 언어에 적용하여, 타입 시스템을 최대한 활용한다. 이는 엄격한 타입(Strict Types)을 가진 함수 시그니처를 통해, 신뢰할 수 있는 인터페이스를 통해서만 객체를 생성하도록 한다. 이로써 컴파일 타임(Compile Time)에 오류를 감지하고, API의 견고함을 높이는 동시에 런타임 에러(Runtime Error) 발생 가능성을 줄인다.

튜플(Tuple) 사용의 한계와 대안

C23의 튜플(Tuple) 기능은 여러 값을 반환하는 데 유용하지만, 익명 태그 타입(Anonymous Tagged Types)에 대한 제약으로 인해 사용에 제한이 있다. 특히 포인터(Pointer)를 포함하는 경우, 컴파일 에러가 발생한다. 작성자는 이러한 문제를 해결하기 위해, 튜플 멤버에 이름을 부여하거나, 구조체(Struct)를 사용하는 방법을 제시한다. 하지만, 튜플의 활용성은 여전히 제한적이며, 더 나은 대안을 모색할 필요가 있다.

결과 반환(Returning Results)을 위한 구조체 활용

작성자는 C 언어에서 sum type을 흉내내기 위해, 결과(Result) 타입을 위한 구조체를 사용한다. 이 구조체는 `ok` 필드를 통해 성공 여부를 나타내고, union을 사용하여 성공 시 `SafeBuffer`를, 실패 시 `ErrorCode`를 저장한다. 이러한 방식은 오류 처리의 명확성을 높이고, 오류 전파(Error Propagation)를 쉽게 만든다. 또한, '파싱 우선, 검증 지양' 철학과 결합하여, 안전하고 효율적인 코드 작성을 가능하게 한다.

some C habits I employ for the modern day