C계열 언어들(C++ , C# 닷넷)들도 MS 비주얼 스튜디오가 아닌 다른 IDE에서 개발하는 것도 가능하다.

 

비주얼 스튜디오 툴이 기능이 많아서 좀 복잡할 때도 있고 가끔은 MinGW 를 쓰기도 한다. 리눅스나 맥 사용자들은 IDE선택에 옵션이 많다.

 

사실 이제 비주얼 스튜디오의 시대는 좀 저물어 가는 느낌도 든다. 오픈 소스 시대에 들어오면서 다양한 옵션들이 많아지고 오픈소스에 맞들린 프로그래머들에서 안티까 꽤 있다. MS 독점 시대의 C개발은 윈도우즈와 비주얼 스튜디오를 거쳐가야 했지만 이제는 그럴 필요가 없다. 구글은 intellij 를 쓴다는 말이 있는데 워낙 큰 회사고 다양한 소프트웨어를 개발하는 회사라서 꼭 한가지의 IDE만 쓸거라고 생각되지는 않는다.

 

아래 문서를 보면 이런 문서를 구글에서 최상단 검색결과에 올려놨다.

구글이 MS를 무시하나...

 

 

Top 10 IDEs for C or C++ Developers in 2020 & Beyond!

IDEs are great for programmers to write an error-free code more efficiently and fast It increases productivity too by providing several features.

blog.eduonix.com

 

하지만 Tiobe 랭킹 사이트에 가보면 여전히 비주얼 스튜디오는 점유율 1위다. 오픈소스인 비주얼 스튜디오 코드와 합치면 34 프로다. 독점까지는 아니지만 역시 1위다.

 

 

MS 비주얼 스튜디오가 업데이트 될때마다 좀 적응하기가 힘들어서 짜증이 날 수 있는데, 그래도 많은 프로그래머들이 디버깅 기능에 있어서는 최고로 쳐주고 있다.

 

MS 비주얼 스튜디오 디버깅

맨날 같은 코드만 반복하다보면 지겨울 때가 온다. 그럴때 디버깅을 켜줘야 할 때다. C의 문법 뒤쪽에 무슨일이 일어나는지 알아보자.

 

우선 처음에는 매우 간단한 코드를 만들고 디버깅 기능 켜보자. 디버깅을 잘 이해하려면 어셈블리언어 지식이 필요하다.(아래의 디버깅은 가장 기초적 어셈블리어가 나온다)

 

#include <stdio.h>

int main(void)
{

	int iData1 = 1;
	int iData2 = 2;
	int iData3 = 3;
	
	int sum = 0;

	printf("%d %p\n", iData1, &iData1);
	printf("%d %p\n", iData2, &iData2);
	printf("%d %p\n", iData3, &iData3);

	sum = iData1 + iData2 + iData3;

	printf("%d %p\n", sum, &sum);

	return 0;
}

 

디버깅을 하려면 중단점을 설정해야 한다. main  함수 안의 첫줄에 중단점을 설정해준다. 마우스 우클릭이다.

 

 

F5를 눌러서 디버깅을 시작하면 중단점 부터 시작한다.

 

아래의 화면은 디버깅 삼종세트이다. 디스어셈블러, 레지스터, 메모리... 그리고 출력을 담당하는 cmd 콘솔창이다.

 

창이 안나온다면 메뉴에서 디버그 -> 창 -> 메모리, 디스어셈블러를 선택한다.

 

메모리 주소 창에 변수의 주소 연산자를 입력한다 여기서는 &iData 이다. 아래와 같이 주소로 이동한다.

 

F10키를 하나씩 누를 때 마다 한줄한줄 어셈블리어를 실행시킨다. 변수할당이 끝났다. 그러면...

 

 

변수가 할당되는 것을 실시간으로 볼 수 있다. 4FFC2C 에서 부터 32비트 정수 값이 1,2,3,0 으로 할당되는 것을 볼 수 있다. C2C 에서 낮은 숫자의 메모리 주소로 이동하고 있다. 리틀엔디안 시스템 이기 때문에 낮은 숫자가 먼저 기록된다. 0 하나의 자리가 1바이트임을 감안하고 봐야한다. 0 자리가 8개 있으니까 32비트이다. (그리고 16진수이다)

 

이 변수들은 main 함수의 스택에 저장된다. 스택은 빠른 메모리이다.

 

디스어셈블리 디버그

다음 어셈블리 라인에는 printf 출력함수가 나온다. iData1 의 값과 메모리 주소를 출력하는 것이다. lea 로 iData 의 주소를 eax에 입력한다. eax 는 메모리 위치가 아니라 CPU의 레지스터 이다. 레지스터를 모른다면 레지스터는 CPU가 직접 컨트롤 하는 작업 공간 정도로 이해하면 된다. 

 

레지스터

EAX의 주소를 잘 보면 변수 iData 의 주소가 입력되어 있다. 16진수가 8개 있다는 것은 32비트라는 말이다. 현재 32비트 주소로 동작하고 있다. 004FFC2C(십진수로 5,241,900) 가 현재 변수 iData가 저장된 메모리 스택의 주소다.

 

lea 명령어는 이 메모리값을 EAX에 복사한다. 그리고 이것을 스택에 Push 한다. 변수의 값인 1도 ECX 레지스터에 입력하여 스택에 Push 한다. 레지스터의 ESP 라고 써있는 곳이 Stack Pointer 스택을 가리키는 주소이다. 그러니까 Push는 변수가 저장된 스택 메모리에서 다시 스택 메모리에 값을 복사하는 일을 하고 있다. 아래의 표시를 보자.

 

cc는 초기화되지 않는 스택 메모리를 뜻한다. 실제 cc라는 16진수 값을 썼는지 무슨 값이 들어있는지 알 수 없다. 어찌됬건 초기화를 하지 않으면 프로그램에서 의미는 없다. 그냥 cc가 아닌 부분을 보면 된다.

 

의미가 있는 것은 1이라는 변수값과 메모리 주소를 복사해서 스택에 할당했다는 것이다. 중간에 cc가 비어있는 것은 컴파일러가 목적을 가지고 비워둔 것으로 보인다. 같은 스택 안에서도 변수를 선언한 스택과 함수에 사용될 스택의 사용 목적에 차이가 있으니 분리한 것 같다.

 

리틀엔디안이므로 거꾸로 거꾸로 저장된다는 점에도 주의를 하자. 처음보면 익숙하지가 않다. 메모리에 보이는 [01 00 00 00]의 의미는 이진수로 아래와 같다. 8비트(1바이트)씩 4개로 잘라서 순서를 뒤바꿔서 저장하는 것이다.

 

당연히 인간에게 익숙하지 않다. 이것은 사람의 이해보다 기계에 친화적인 방식이다.

0000 0000 0000 0000 0000 0000 0000 0001 (32비트 2진수) 1
0000 0001 0000 0000 0000 0000 0000 0000 (리틀엔디안)

 

 

마지막으로 프로시저를 호출하여 콘솔에 문자열을 출력하고 스택포인터에 C(십진수 12 -> 즉 4바이트 정수형 3개)를 더한다. 일단 스택포인터가 올라가면 그 아래에 있는 데이터들은 아직 남아 있지만 더이상 접근할 수가 없다. 결국 다음 스택 사용시에 덮어 씌워지게 된다.

스택

 

C언어에서서는 스택의 이해가 중요한데 스택은 컴파일 시점에 미리 예측된 메모리 공간이라서 CPU의 성능이 잘 나오는 장소이기 때문이다.

 

CPU의 작업장? 이렇게 비유 하면 좀 웃긴데 스택이 CPU가 빠르고 효율적으로 일할 수 있는 안쪽 작업장이라면 히프 영역은 바깥에 나가서 해야하는 작업이다. 스택 메모리는 작고 (컴파일러에 따라 다르지만 VS 는 윈도우 환경에 따라 기본 1메가로 설정 되어 있다. 변경가능) 히프 메모리는 그 보다 광대하다. 위 주소체계를 보면 32비트는 4기가까지 메모리 주소 할당이 가능하다. 바이트로 비교하면 스택은 1000개 힢은 42억개 정도가 된다. (단순비교다)

 

작업장 (스택)
야외 히프(HEAP)

 

자, 그럼 끝의 두 문장을 보자. 마찬가지 방식이 적용될 것이란 걸 예상할 수 있다.

sum = iData1 + iData2 + iData3;

printf("%d %p\n", sum, &sum);

세개의 변수를 더하는 일은 어셈블리어로 봐도 어렵지 않다.

 

eax 레지스터 하나로 처리가 가능하다. 이런 표현식을 다룰 때는 C언어 챕터에 나온 연산자의 우선순위가 적용된다. = 기호의 오른쪽 부터 연산이 시작된다. eax 에 iData1 을 넣는다. 그 다음엔 iData2를 eax 에 가산한다. iData3까지 가산하는데 eax 레지스터 하나만 필요하다. 처음에 변수를 스택 메모리에 저장했기 때문이다. 여기까지 변수의 값은 하나도 변하지 않았다. 

 

네번째 줄에선 데이터의 방향을 바꿔서 eax를 sum에 저장한다. 이 예제 코드에 변수를 네개 선언했다. 아래로 차곡차곡 쌓여있다. (아래라는 말은 메모리 주소상으로 내려가고 있기 때문이다. (2C -> 1E -> 10) 스택 포인터를 원위치 시킬 때 왜 ADD 명령어를 썼는지 알 수 있다. 스택 포인터를 올리는게(ADD하는게) 원위치 시키는 것이다.

 

 

 

출력하는 법은 같다. eax에 주소를 ecx에 값을 넣고 스택에 Push 한다. 표준출력함수의 호출이 끝나면 스택포인터를 원위치 시킨다.

 

결과창 콘솔

이렇게 해서 디버그가 끝났다. 아주 기초적인 C언어 예제인데도 불구하고 그 내부 사정은 여간 복잡한게 아니다. 아직 여기서 끝난게 아니다. 컴퓨터 구조의 내부로 깊게 들어갈 수록 더 많은 복잡한 단계들을 다루어야 한다. 크기가 작은 예제 프로그램이 이정도면 크기가 크고 네트워크가 된 프로그램은 어떻겠는가? 상상을 초월하게 느껴진다.

 

컴퓨터 구조와 추상화 계층의 이해 (어디에서 서있을 것 인가?)

 

그렇다면 과연 어느정도까지 알아야 C/C++ 을 잘 한다고 할 수 있을까? 글쎄... 거꾸로 C/C++을 잘 한다는게 뭘까? 라는 질문은 어떨까? 질문속에 답이 있다. 이 세상 모든 사람들에게 오로지 하나의 틀만 적용해야 한다고 믿으면 C/C++을 잘하는 기준을 세울 수 있다.

 

그런데 세상이 변하는 속도나 컴퓨터 공학이 변하는 속도나 비슷해 보인다. 컴퓨터가 4차 산업의 핵심으로써 변화의 가속을 부추기기 때문이다. 빠르게 변화하는 세상속에서 만약 오늘의 기준이 내일 바뀌게 되면 얼마나 가치가 있을까? 당연히 가치가 떨어질 것이다. 가치는 사람들이 부여하는 것이기 때문이다. 그 사람들이 과거의 사람들일 수 있고 현재이거나 미래일 수도 있다. 오늘만 살면 문제는 없다. 오늘의 가치만 따지면 되니까.

 

코딩을 하면서 내가 어디 서있는가라는 질문은 중요하다. 어디 서있는가 내 가슴이 어디를 향해 있는가? 그 모습으로 현재와 미래의 가치를 이야기할 수 있기 때문이다.

 

사실 일반적인 컴퓨터 전문가가 되기 위해서 이러한 지식들은 거의 쓸모가 없다. 물론 더 많이 더 잘 아는 사람이 잘할 수는 있을 것이다. 그러나 그러기 위해서는 시간이 많이 필요하다. 소위 기술 영업에 전문한 경영자가 되기 위해 꼭 밑바닥에서 부터 접근해야 할 필요는 없다. 어떤 사람들은 본능적으로 기술에 적응한다. 컴퓨터처럼 보이지 않는 기술을 보이는 것처럼 설명을 잘하고 고객의 눈높이에 맞춰준다. 사실 이런 사람들의 영향력이 크고 돈을 잘 버는 시대다. 그것도 어마어마한 금액으로.

 

애플 스티브 잡스의 후대 평가는 어떤가? 초창기 매킨토시를 개발한 차고에서 부터 스티브 워즈니악이 기술을 담당했으며 잡스는 위대한 IPHONE의 마케팅을 완성했다. 한때 대립관계에 있던 빌게이츠도 스티브 잡스의 연설 영상은 컴퓨터에 저장해서 돌려 봤다고 한다.

 

기술과 영업 두가지를 다 잘하는 사람은 많지 않다는 것을 알 수 있다. 아니 둘다 잘해도 한가지에 집중한다는 표현이 맞을 것 같다. 지금의 시대가 애매하긴 해도 여전히 전문성에 의해 분화되있어서 여러가지를 잘해도 한가지에 집중하는 사람이 더 성장을 하는 시스템이다.

 

C언어를 파는 사람들은 컴퓨터 덕후의 기질이 좀 있다. 이것은 일상의 언어로 사람들과 공감하기 어렵다. 위에서 CPU를 의인화 시킨 비유를 들기도 했지만 비유는 주로 쉬운 이해를 통해 사물을 이해하는 단계에서 의미가 있다. 매번 비유를 길게 하는 것도 별로 효율적이지 않다. 그리고 비유의 한계는 정확하지 않다.

 

디버깅은 C/C++을 만족스럽게 다루기 원하는 사람들에게 필요한 수많은 기술중의 하나이다. 많은 교재들과 온라인 설명들, 그리고 심지어 대학의 강의까지 있지만 너무 추상적이다. 모르겠다 그럴 때 디버깅 툴을 열어야 할 때이다. 거기서는 CPU와 메모리, 컴파일러가 무엇을 하고 있는지 런타임에 무슨일이 일어나는지 들여다 볼 수 있다. 그런면에서 비주얼 스튜디오의 디버깅 툴은 세계적으로 최고로 인정받고 있으니까 시간을 투자할만 하다.

 

C/C++을 더 깊게 들어가고 싶지 않다. 나는 스티브 잡스처럼 되는 것을 희망한다면 좀 더 기술을 일상의 언어영역으로 끌어와서 대중적 커뮤니케이션에 더 에너지를 쏟는게 좋다. 디버깅 툴을 열어놓고 메모리를 쳐다 보는 시간보다 더 유용할 것이다.

 

혹은 다른 선택지도 있다. 두개 다 잘하는 것이다. C언어의 기술도 뛰어나고 기획과 마케팅도 뛰어난 것이다. 큰 회사에서는 한가지 분야에 특화되는 사람이 중요한 역할을 하지만 대부분의 중소기업에서는 그렇지 않다. 능력적으로는 다들 비슷한 보통의 사람들이기 때문이다. 그러므로 두가지를 다 잘하면 금방 두각을 나타낼 수 있다. 그런데 한가지를 잘 하는것도 어려운데 두 가지를 잘하는 것이 가능할까?

 

결론적으로 가능하다. 이 세상에 초인들은 많다. 남들이 잠잘 때 공부하고 남들이 술마시고 영화볼 때 운동하고 남들이 세시간에 하는 일을 30분에 하는 사람들은 생각보다 많다. 그게 그렇지 않은 사람이 옆에서 보면 썩 기분이 좋지는 않다. 세상이 불공평하게 느껴지기 때문이다. 한편 마음을 다잡을 수도 있다. 노력을 더 해야겠다고. 그런데 요새는 노오력 노오력이라고 해도 안되는 사람들이 많아져서 결국은 포기한다는 의미인 소확행이나 욜로 같은 개념이 만연해졌다.

 

솔직히 글쓴이도 운명론자 관점이 있다. 세상을 살다보니 인명재천 사람의 뜻대로 되지 않는 일이 많다. 아마 이 세상이 자신만의 무대라고 믿는 사람들을 위해 만든 사자성어라고 생각한다. 기술과 영업(경영) 이 두가지를 잘하는 이는 하늘이 내린 사람일 가능성이 많다. 그의 지금 모습을 보지 말고 어떻게 살아왔는지 뜯어보면 그런 사람들은 하늘이 만든 사람들 처럼 모든게 맞아떨어지는 경우가 많다. 또 안 풀리는 사람도 마찬가지고.

 

C언어 간단한 디버그 하나를 하면서 뭔 그리 말이 길어지나. 그렇게도 생각한다. 그런데 이게 추세가 될 거라고 생각한다. 예전처럼 양산형 공돌이 이런 좀 낮은 가치의 시각은 바뀌게 될 것이다. 대형서점에 가보면 컴퓨터공학과 인문이 녹아있는 책들이 매대에 나와있다. 그래야 좀 더 대중적이 될 수 있다고 믿는다.

 

C/C++ 책으로 유명하신 최호성 저자의 말처럼 컴퓨터 프로그래밍을 하는 것은 글을 쓰는것과 같다고 한다.

(물론 늬앙스는 좀 달랐지만)

 

그러고 보니 코딩 자체가 글 아닌가? 영작문. C 언어/어셈블리어 시절에는 철저히 기계의 문법에 맞춰서 썼다. 자바와 파이썬으로 이어지면서 사람이 알아듣기 쉽게 변했다. 일본인이 만든 루비라는 프로그래밍 언어는 쉽게 재미있게 하기 위해서 만들었다고 한다. 지금은 주춤하지만 세계적으로 상당한 반응을 얻어서 일본인이 만든 프로그래밍 언어 중에 최초로 국제 표준을 받았다.

 

컴퓨터를 설계한 사람들은 기계와 인간 그리고 다른 사물간의 관계에 대해서 오랫동안 분석해왔다. 그래서 그들이 취한 방법은 위에서 CPU의 비유라고 말한 것과 어쩌면 본질적으로는 같은 방식이다. 그리고 그게 이 포스팅에서 말하려는 취지일 것이다.

 

그들은 추상화 계층이란 것을 만들어 냈다. 그리고 추상화 개념을 통해 가상화를 실현했다.

 

과학자들은 컴퓨터의 세계를 구축하면서 인간의 사회와 닮은 하나의 거대한 시스템으로 이루어진 생태계를 창조하였다. 인간 사회의 모방일 수도 있고... 인간이 만든 것이라서 그렇다. 전자와 기계로 만들어진 컴퓨터지만 최종적으로는 인간이 관리해야 하기 때문에 인간의 인식을 벗어나기는 쉽지 않다.

 

인간의 추상화 능력을 사용해서 컴퓨터 생태계를 관리하는게 가장 효율적이라 생각한 것이다. 직관적이기도 하고.

 

그래서 컴퓨터는 추상화로 이루어져 있다. 애플리케이션 계층, OS 계층, 하드웨어 계층 그것이 네트워크로 확장되면 또 거기에 필요한 추상화 계층이 생긴다.

 

우리가 흔히 이야기 하는 C언어의 포인터에 대해서 보면 C언어는 다른 언어와 다른 특별한 능력을 갖는다. 직접적으로 메모리에 손을 댈 수 있기 때문이다. OS와 Runtime 환경이 관리해야할 일을 함으로써 유일하게 다양한 추상화 계층(OS, 하드웨어, 애플리케이션 (고수준/저수준)) 을 넘나들 수 있도록 만들어진 것이다. 게다가 C++에서 객체지향을 활용한 고수준의 프로그래밍도 가능하다.

 

많은 프로그래머 들이 왜 최고의 도전과제로 삼는 것이 C와 C++ 인지 알 수 있다. 기계어를 다루는 어셈블리어나 다른 언어도 있지만 왜 C가 최고인것일까 알 수 있는 대목이다. 그만큼 이슈로 생각하기 때문에 호불호나 진영이 갈라진 악평도 있다.

 

반면 자바나 파이썬 처럼 메모리에 직접 손을 댈 수 없는 언어들은 좀 더 소프트하고 추상적이다. 우리가 할 수 있는 것을 하면되~ 라는 개념에서 보는 것이다. 이들은 하드웨어 사양이 발전하면서 점점 더 가치가 높아지고 있다.

 

다시 원점으로 돌아가서 디버그를 하는 C/C++ 어느 수준까지 도달해야 잘하는 것일까? 그 질문보다 어떤 추상화 계층에 서있어야 하는가라는 질문이 먼저 필요하다.

 

모든 영역을 다 파고 들고 싶다. 그러면 C/C++ 이 필요하다. 포인터 부터 객체지향에 네트워크까지 다루게 된다. 코드를 이해하는 것은 최고 수준에 도전할 수 있기 때문에 이들은 무엇이라도 할 수 있을 것이다. C/C++을 할 수 있다면 다른 언어에 접목시키는 것이 가능하다. C 자체가 운영체제를 작성하고 크로스 플랫폼으로 이식할 수 있다.

 

UX로 사람들과 소통하는 일이다. 그러면 프론트엔드에서 사람들과 소통해야 한다.(말그대로 front-end 앞단에 있으니 당연히 앞에 있는 사람들과 소통해야 한다) 그런데 프론트엔드는 조금 욕심을 내서 자바스크립트 풀스택까지는 바라봐야 하지 않을까 싶다. 아무래도 UX라는게 전문화된 일자리로써 지속될지는 다소 의견이 분분하다. 스마트폰 이후 새로운 방식의 인터페이스가 어떻게 나올지 아무도 알 수 없다. VR이 될지 뭐가 될지. 스스로 시장을 창조하는 디자이너가 될 수 있다면 모를까 기능만 가지고는 한계가 빨리 올 것 같다.

 

백엔드 서버 개발자이다. 이들은 포인터와 메모리 관리를 할 수 있는 사람들이다. 서버의 순간순간의 자원들이 완벽하게 돌아가기 위해서는 백엔드의 설계가 필요하고 별도의 지정된 관리자가 필요하다. 이제는 AWS와 같은 클라우드 컴퓨팅 관리 기술이 중요해졌는데 그렇다고 관리자가 없어도 된다는 것은 아니다. 서비스가 잘 작동하고 있는지 24시간 관리해야 한다. 웹 앱, 모바일 앱, 게임 앱 등 이 다 마찬가지다.

 

이들 말고도 수많은 사람들이 있다. 과학자들이 설계한 추상화 계층에 맞춘 일을 담당할 수 있는 IT기술자들이다. 앞으로도 이전 세상에 없었던 새로운 직업들이 생길 것이다. 기술이 변해서 구조가 변하면 그것을 담당할 직업이 필요해 지기 때문이다. 어떤 직업이냐 결정하는 것은 역시 추상화 계층에 달려 있다.

 

마지막으로 자신에게 해야하는 마지막 질문을 생각해본다.

 

"나는 어느 추상화 계층에 살고 싶은가?"

 

그 계층에 갈 수 있도록 안내해주는 언어가 당신의 언어가 될 것이다. 프로그래밍 언어건 의사 코드건(pseudo code)

공유하기

facebook twitter kakaoTalk kakaostory naver band