리눅스 커널에 러스트를 통합하는 과정에서 드러난 READ_ONCE/WRITE_ONCE의 의미적 모호성을 계기로, 러스트 생태계가 API의 의미 보장을 가능한 한 정밀하게 표현하려는 문화적 규범을 어떻게 발전시켜 왔는지 살펴본다.
의미적 정밀성에 대한 러스트의 문화
2026년 1월 16일 · 3분 읽기 · 주제: Rust
지난주 LWN은 “READ_ONCE(), WRITE_ONCE(), but not for Rust”를 발행했는데, 이는 리눅스 커널에 더 많은 러스트를 통합하는 과정에서 마주친 한 가지 문제를 다룬 글이었다. 요지는 READ_ONCE와 WRITE_ONCE 매크로가 실제로는 서로 다른 맥락에서 서로 다른 목적을 위해 사용되고 있으며, 그 결과 일관되지 않은 의미적 보장(semantic guarantees)들의 집합을 암묵적으로 인코딩하고 있다는 점이다. 이어서 해당 글은, C 쪽에서 이런 매크로를 사용하는 API의 러스트 측에서, 그와 연관된 구체적인 의미적 보장을 어떻게 하면 더 정확하게 표현할 수 있을지 결정하기 위해 리눅스의 러스트 기여자들이 어떤 식으로 작업하고 있는지 설명한다.
이런 상황—하나의 API가 여러 개의 서로 다른 의미적 보장을 암묵적으로 인코딩하고 있음을 식별한 뒤, 그것들을 분리해 내고 싶어지는 상황—은 러스트 개발자들에게는 익숙한 것이다. 러스트 생태계에서 비교적 잘 이야기되지 않는 문화적 규범 중 하나는, API는 의미적 보장을 가능한 한 정밀하게 인코딩하도록 설계되어야 한다는 것이다.
이는 컨테이너 타입의 설계, 예컨대 러스트의 다양한 “셀(cell)” 타입들(Cell, RefCell, OnceCell 등)에서 드러난다. 또한 포인터와 연관된 타입들, 예를 들어 Unique(러스트 표준 라이브러리 내부 타입으로, 그 안에서 많이 사용된다)나 NonNull(std::ptr API의 일부)에서도 마찬가지다. Manish Goregaokar가 “Wrapper Types in Rust: Choosing Your Guarantees”에서 설명했듯이, 러스트는 사용자가 서로 다른 고유한 의미적 보장들을 분리해 낼 수 있게 하며, 사용자는 그 보장들을 조합해 자신이 필요로 하는 것을 정확하게 표현할 수 있다.
또한 이는 더 높은 정밀성을 가능하게 하기 위해 Copy / Clone 트레이트 계층을 수정(amend)하자는 러스트의 지속적인 논의에서도 나타난다. Copy는 사소하게(trivially) 복사 가능한 타입을 위한 트레이트로, 전체 내용이 단 한 번의 memcpy로 복사될 수 있음을 의미한다. Clone은 더 “비싼” 복사를 위한 것으로, 예컨대 힙에 있는 데이터를 복제하고 포인터를 조정해 복제된 데이터를 가리키게 해야 하는 복사 등이 여기에 해당한다. 시간이 지나며 러스트 개발자들은 또 다른 형태의 복사 의미론을 가진 타입들을 확인해 왔다. 예를 들어 Rc나 Arc처럼, 데이터를 복제(clone)한다는 것이 실제로는 데이터 자체가 아니라 그 기반 데이터(underlying data)에 대한 _핸들(handle)_을 복제하는 것을 뜻하는 경우다.
러스트 커뮤니티가 정밀한 의미론을 원한다는 점은, 장기적으로 더 견고한 소프트웨어 시스템으로 이어진다. 단기적으로는—리눅스 개발자들이 겪고 있듯이—이전에는 보장과 요구사항이 더 모호했던 시스템에 더 높은 의미적 정밀성을 도입하는 일이 어려울 수 있다. 개인적으로 나는 러스트가 이런 규범을 가지고 있다는 점이 좋고, 이는 단지 언어로서의 러스트뿐 아니라 _문화_로서의 러스트에서 매력적으로 느껴지는 부분이다. 그리고 나는 그 덕분에 리눅스도 더 나아질 것이라 낙관한다.
저작권 Andrew Lilley Brinker. 캘리포니아에서 제작됨