c++에 관심이 많거나 자주 쓰는 챈럼 중에는 공식 레퍼런스나 기타 문서 등에서 undefined behavior 라는 말을 한번씩 본 적이 있을 거야. 예를 들어서 std::vector::operator[] 의 설명 중 "Accessing a nonexistent element through this operator is undefined behavior." 라거나.

그런데 이 undefined behavior란 걸 매번 꼬박꼬박 적어두는 걸 보면 중요한 거긴 할 텐데, 뭐길래 그렇게 중요한 걸까?


Undefined behavior는 내가 연구하는 분야에서 상당히 자주 쓰이는 용어야. 이걸 번역하면 '정의되지 않은 행위'인데, 표현이 좀 어색하지? 배경 지식이 없어서 어색하게 느껴지는 거기도 하겠지만, 우리끼리도 이게 썩 안 와닿아서 줄임말로 UB라고 부를 정도니 벌써 겁먹진 않아도 괜찮아. 컴공 용어가 대부분 번역이 영....


그래서 행위가 뭐길래 정의가 안 됐다는 걸까?

Behavior(행위)는 정말 간단하게 설명하자면 프로그램의 동작이야. 예를 들어 1+1을 계산한다거나, 텍스트가 출력된다거나, 화면이 전환된다거나, 파일을 새로 쓰거나 읽거나, 프로그램이 꺼지거나(?) 하는 모든 게 behavior야.

이 말을 조금 비틀면, 프로그램이란 건 behavior의 연속이라는 말도 돼. 즉 어떤 프로그램은 하나 이상의 behavior를 일으킨다/실행한다고 할 수 있는 거야. 여기서 조금 더 나아가면, 우리가 프로그래밍을 한다는 건 어떤 프로그램의 behavior를 정의한다는 뜻이란 거지.


글빨이 딸려서 중간중간에 좀 비약이 있었지만, 어찌저찌 행위도 나오고 정의도 나왔지?위에 나온 말대로면 '정의된 행위'란 건 프로그래머가 짠 프로그램, 또는 코드의 behavior를 의미한다는 걸 알 수 있을 거야.... 아마도....

근데, 그럼 정의되지 않은 행위는 뭘까? 프로그래머가 짠 프로그램 behavior의 반대니까 프로그래머가 짜지 않은 behavior란 뜻인가? 프로그램이 갑자기 시키지도 않은 일을 일으키는 걸까?


놀랍게도 그게 맞아. Undefined behavior는 프로그래머가 정의하지 않은 behavior, 즉 프로그래머가 의도하지 않았음에도 프로그램이 벌이는 behavior야.

여기 챈럼들은 대부분 전공 수업에서든 인터넷에서든 "컴퓨터는 철저히 사람이 시킨 대로만 돌아간다"는 말을 한번쯤 들어봤을 거야. 그런데 컴퓨터가 갑자기 사람이 시키지도 않은 일을 한다니, 이게 어떻게 된 걸까?


컴퓨터 아키텍처나 컴파일러 수업을 깊게 배웠다면 알게 되는 사실인데, 사실 컴퓨터는 사람이 시킨 대로만 돌아가지 않아. 정확히는, 사람이 시킨 대로 하지 않았을 때 겉에 드러나는 결과가 동일하고 일을 더 빠르게 끝낼 수 있다고 판단하면 사람이 시킨 것과 다르게 돌아갈 수도 있어.

예를 들어 어떤 멍청한 프로그래머가 2 + 2 + .. + 2 를 40번 한 뒤에 그 결과를 출력하는 코드를 짰어. 컴파일러는 이걸 보고 "이걸 보는 사람은 어차피 2를 40번 더하든 2 * 40을 하든 80을 써버리든 차이를 모를 텐데, 그냥 80으로 바꿔버려야지" 라고 판단해서 코드를 멋대로 바꿔버릴 수도 있는 거지.

즉 겉에 드러나지 않는 behavior를 바꿈으로써 겉에 보이는 behavior를 동일하게 유지하되 더 빠른 코드를 만드는 거지, 이게 바로 컴파일러 최적화야.


하지만 이런 최적화들에는 '잘 동작하는' 전제 조건이 있어. 이게 프로그래밍 언어의 문법과는 결이 좀 다른데, 딥다크한 내용을 생략하고 차이점을 말해주자면 컴파일러 입장에서 코드가 문법에 맞는지 체크하는 건 정말 간단한데, 코드가 전제 조건을 잘 지켜서 쓰였는지 알아내는 건 아주 어려워. 그래서 컴파일러는 프로그래머가 어련히 잘 짰을 거라고 믿고 코드를 최적화하는 수밖에 없어.


그런데 여기서 프로그래머가 컴파일러의 기대를 배신하면 어떻게 될까? 최적화가 잘못 동작하면 프로그램이 잘못 변형될 거고, 원래는 존재하지도 않던 behavior가 생겨날 수도 있어. 이런 게 바로 정의되지 않은 행위, 즉 undefined behavior야!

그래서 이런 전제 조건을 이야기할 때 자주 쓰이는 표현이 "이런이런 걸 하는 코드는 undefined behavior를 일으킨다"이고, 해석하면 "이런 식으로 코드를 짜면 컴파일러가 네 프로그램을 조져버릴 수 있다" 라는 경고야.

 

그러니까 착한 컴붕이들은 프로그래밍을 할 때 언어 명세를 잘 읽고 undefined behavior를 일으키는 코드를 짜지 않도록 노력해 보아요~




근데 왜 블챈펌이냐고?


원래 이번 블루 아카이브 총력전 (보스 레이드 같은 거야) 브금 제목이 "Undefined Behavior" 라서 쓴 글이거든 :o

컴공챈에는 내용을 좀 더 딥다크하게 보충해서 쓸까도 고민중이긴 한데... 그몬씹 소리 들을 만한 내용이라 잘 모르겠담;