c언어 메인함수 정의? 질문드립니다

pjoos139의 이미지

c언어는 main함수가 무조건 포함되어있는걸로 알고있습니다
여기서 궁금한점은 예를 들어 c언어로 만든 프로그램을 다수 실행시키면 컴퓨터 메모리에서는 다수의 프로그램에 존재하는
같은 명칭을가진 메인함수를 어떻게 구분하는지 궁금합니다

제 생각에는 프로그램실행 할때 하드디스크에서 메모리로 복사하는 과정에 메모리 영역을 지정해줌과 동시에 주소를 부여하여
영역안에서 구분하는것으로 알고있는대 이것이 맞는것인지 궁금합니다

vagabond20의 이미지

더 구체적이고 교과서적인 설명은 다른분께 미루고 제가 아는선에서 답변을 드리자면,
C 프로그램의 모든 함수는 결국 다른 프로그램혹은 같은 프로그램 내부에서 불러 사용하는 반면, main 함수는 항상 운영체제 (Operating System) 가 불러서 실행합니다.

순서를 보면 대략,
(1) 사용자나 다른 외부의 프로그램이 해당 프로그램을 (우리가 main 을 기동시키지 않고 프로그램 이름으로 실행하는 식으로) 기동시킵니다.

(2) 해당 프로그램 (main 함수가 entry point 인) 이 기동되면 운영체제가 콘트롤을 넘겨받고 메모리상의 사용가능한 주소를 지정하여 그 프로그램의 main 함수를 불러 실행시킵니다. 실행된 프로그램은 main 함수를 시작으로 프로그래밍된 순서에 의해 작업을 시작하고 마칩니다. 그럼 다시 운영체제로 콘트롤이 넘겨집니다.

이것은 똑같은 C 프로그램을 동시에 두개 혹은 세개 실행시켜도 각 instance 의 main 함수는 별개의 프로그램인것 처럼 작동하는 원리입니다. 왜냐하면 지정되는 주소가 모두 서로 다르기 때문이지요.

예를 들어 똑같이 C 언어로 짠 TCP/IP line driver 프로그램을 그 사용목적에 의해서 6 개를 각각 다른 parameter 로 부르면 6 개 프로그램의 main 함수는 각각 별개의 프로그램내 함수로 운영체제가 구분해서 동작시키는것이지요. 그런식으로 시스템과 시스템간 data 를 여러채널 (같은 C code, 그러나 다른 instance) 을 통해 주고받습니다.

여의도자바

pjoos139의 이미지

설명을 잘해주셔서 이해하는대 큰도움이 되었습니다 좋은 답변 감사합니다

나빌레라의 이미지

단순한 의문이지만 그 의문에 대한 답은 꽤 복잡합니다.

우선 OS가 프로그램을 실행할 때 어떻게 main() 함수를 찾는지부터 공부해야 합니다. 이걸 알려면 로더(loader), 메모리 재배치(memory re-location), 엔트리 포인트(entry point) 등이 뭔지 알아야 합니다.

잠깐 언급하자면, 리눅스나 윈도우는 엔트리 포인트가 main() 함수가 아닙니다. 실제 라이브러리에서 자동으로 넣어주는 엔트리 포인트 함수가 있습니다. 그래서 C++의 생성자 함수등이 main()보다 먼저 동작하게 만들 수 있는 것이고요. 물론 링커의 옵션을 조정해서 시스템의 디폴트 엔트리 포인트를 생략할 수도 있습니다. 이런것들도 제가 윗 문단에 언급한 용어를 알아야 이해하고 써먹을 수 있습니다.

키워드를 알려드렸으니 찾아서 공부해 보시기 바랍니다.

또한 여러 프로그램이 메모리 주소를 사용하는 것은 페이징(paging)을 알아야 합니다. 이것도 키워드를 따라서 찾아보세요.

그리고 손으로 작성한 프로그램 소스 코드가 진짜 프로그램으로 바뀌면(컴파일되면) 함수 이름이나 변수 이름은 의미가 없어집니다. 메모리 주소로 바뀌지요. 함수 이름이나 변수 이름은 심볼(symbol) 정보로 별도로 존재합니다. 심볼 정보는 없어도 프로그램은 실행되고요, 사람이 디버깅할 때 필요합니다.

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

pjoos139의 이미지

답변 감사합니다 제시해주신 키워드도 찾아서 공부하겠습니다

Stephen Kyoungwon Kim@Google의 이미지

c언어는 main함수가 무조건 포함되어있는걸로 알고있습니다 여기서 궁금한점은 예를 들어 c언어로 만든 프로그램을 다수 실행시키면 컴퓨터 메모리에서는 다수의 프로그램에 존재하는 같은 명칭을가진 메인함수를 어떻게 구분하는지 궁금합니다

제 생각에는 프로그램실행 할때 하드디스크에서 메모리로 복사하는 과정에 메모리 영역을 지정해줌과 동시에 주소를 부여하여
영역안에서 구분하는것으로 알고있는대 이것이 맞는것인지 궁금합니다

핵심은 아마 프로그램 별로 프로세스 위에서 돌아가고 프로세스는 독립된 (가상) 메모리 공간을 가진다는 것으로 보입니다.

일단 프로그램이 로드가 된 상태에서는 main이라는 심볼은 없어지고 주소로 대체됩니다. 그리고 이 주소는 그 프로그램이 수행 중인 프로세스의 virtual memory space 상의 주소입니다. 다른 프로그램/프로세스는 이와 분리된, 자기 고유의 memory space를 가지기 때문에 뒤섞이지 않습니다.

load를 할 땐 loader에게 main 함수든 뭐든 필요한 만큼만 주어집니다. 이를테면 main이 두 개라면 링크가 되지 않겠죠. 물론 sort라는 프로그램을 빌드 하는 동안 firefox라는 프로그램에도 main이 있을 수 있는데, 그건 링커에게 sort를 빌드할 때 입력으로 주어지지 않습니다. 로더는 링커가 남긴 정보를 보고 추가로 주소 계산을 하게 될 텐데, firefox의 메인 주소와 같은 정보는 링커가 남기지 않을 거고 로더에게 전달되지 않겠죠.

문제가 있다면, 링크할 당시 빌드 시스템의 라이브러리가, 실행 파일이 수행될 타겟 시스템의 라이브러리와 호환되게 되어 있는데 뭔가 잘못되어 차이가 나는 정도일 거 같은데.. 이것도 심볼이 중복되는 것 같은 기초적인 오류는 안 생기도록 프로토콜이 잡혀 있을 겁니다.

pjoos139의 이미지

질문에 답해주셔서 감사합니다 이해하는대 도움이 되었습니다