정의되지 않은 동작 약 100개 중 45개, C 표준이 걷어낸다

C2y 초안이 UB를 줄이는 게, C를 직접 안 쓰는 1인 개발자한테 왜 체감되는지 적어요.
npm install 하다가 node-gyp 에러 나서 Xcode 커맨드라인 툴부터 깔아본 적 있으세요? 저는 이미지 리사이즈 라이브러리 하나 때문에 처음 겪었어요. 그때 알았죠. 제 Next.js 앱 밑바닥 어딘가엔 결국 C가 돌고 있다는 걸요.
그래서 이번에 GeekNews에 올라온 글이 눈에 들어왔어요. C 표준 위원회가 정의되지 않은 동작(Undefined Behavior, 줄여서 UB)을 줄이고 있다는 소식이에요. 진행 중인 C2y 초안이 기존 표준의 약 100개 UB 항목 중 45개를 걷어냈다고 해요.
정의되지 않은 동작은 왜 위험할까요?
C에서 UB는 "이 경우엔 표준이 아무것도 약속하지 않음"이라는 뜻이에요. 컴파일러한테 요구사항이 없으니, 컴파일러는 "그런 일은 일어나지 않는다"고 가정하고 최적화를 해요. 글에서도 이 지점을 짚어요. 컴파일러의 공격적인 최적화와 개발자가 기대하는 동작 사이가 벌어진다고요.
개발자 입장에선 이게 제일 당황스러워요. 내 머릿속엔 "오버플로 나면 그냥 음수로 돌겠지" 같은 그림이 있는데, 컴파일러는 그 경우 자체를 없는 셈 쳐요. 그래서 디버그 빌드에선 멀쩡하다가 최적화 켜고 배포하면 분기 하나가 통째로 사라지는 식의 삽질이 생겨요.
UB는 버그가 아니라 "버그인지 아닌지 표준이 말해주지 않는 구간"이에요. 그 구간을 좁히는 게 이번 초안이에요.
C 안 쓰는데 이게 왜 상관있냐면
혼자 만드는 사람은 보통 C를 직접 안 써요. 저도 TypeScript랑 Python이 거의 전부예요. 그런데 돌려보면 결국 C 위에 서 있어요. 이미지 처리, SQLite 바인딩, 암호화 라이브러리, Postgres랑 Redis 자체까지요.
그 라이브러리들이 어떤 컴파일러, 어떤 최적화 옵션으로 빌드됐는지 저는 몰라요. 배포 플랫폼 바뀌면 바이너리도 바뀌고요. UB 구간이 줄면, 같은 소스가 컴파일러마다 다르게 도는 여지가 그만큼 줄어요. 제가 직접 고칠 수 있는 영역은 아니지만, 밑바닥이 조금 덜 흔들리는 방향인 건 맞아요.
그림 1.
AI가 뱉는 C 코드는 어떤 C일까요?
요즘은 작은 네이티브 모듈이나 CLI를 AI한테 시켜서 C로 뽑는 경우도 있잖아요. 그 모델이 학습한 C는 수십 년치 코드예요. UB를 알고 피한 코드보다, 우연히 잘 돌던 코드가 훨씬 많을 거라고 봐요. 이건 제 추측이에요.
컴파일 통과했다고 안심하기 어려운 이유가 여기 있어요. C는 틀린 코드도 조용히 컴파일돼요. 표준이 UB를 줄이면 "컴파일됐는데 왜 이래"의 범위가 좁아지는 셈이라, AI 코드 받아쓰는 입장에서도 언젠가 체감이 올 거라고 기대해요.
그런데 당장 달라지는 건 없어요
초안이에요. 표준이 확정돼도 컴파일러가 구현해야 하고, 이미 깔린 라이브러리는 기존 컴파일러로 빌드된 채 그대로예요. 어떤 45개가 빠졌는지도 GeekNews 요약만으론 알 수 없어요. 원문을 봐야 해요.
| 구분 | 내용 |
|---|---|
| 기존 표준의 UB 항목 | 약 100개 |
| C2y 초안에서 제거 | 45개 |
| 남는 항목 | 약 55개 (단순 뺄셈, 초안 기준) |
숫자는 이게 전부예요. 그래도 "컴파일러 마음대로" 구간이 절반 가까이 줄어든다는 방향 자체가 저한텐 반가워요.
직접 해 보려면
- C 코드가 조금이라도 있다면 clang이나 gcc에
-fsanitize=undefined를 붙여서 한 번 돌려보세요. 런타임에 UB를 잡아주는 옵션이에요. - 내 프로젝트에 네이티브 모듈이 몇 개인지 세어보세요.
find node_modules -name binding.gyp정도면 대충 보여요. 미리 빌드된 바이너리를 쓰는 패키지는 안 잡힐 수 있어요. - AI한테 C 코드를 받았으면 "이 코드에 정의되지 않은 동작 있어?"를 한 번 더 물어보세요. 답이 틀릴 수 있으니 sanitizer로 확인하는 게 맞아요.
이걸로도 안 되는 것
- UB 항목이 줄어도 C가 메모리 안전한 언어가 되는 건 아니에요. 동작을 "정의"하는 것과 그 동작이 안전한 건 다른 얘기예요.
- 초안이라 실제 컴파일러 동작이 바뀌는 시점은 아직 몰라요. 저도 확인 못 했어요.