함수의 중첩 정의

C언어에서는 함수를 중첩 정의하는 것을 허용하지 않는다.

예를들어, C언어에서 다음과 같은 함수를 생각해 보자.

#include

int test(int a){

printf(“a “);

int nested_test(int b){

printf(“nested”);

return 1;

}

return nested_test(1);

}

int main(){

test(0);

return 1;

}

test함수 안에 nested_test함수가 또 정의되어 있다. C언어 표준에서는 이런 함수 정의를 허용하지 않는다. 그러나 GCC의 C컴파일러에서는 허용한다. 위의 프로그램을 실행시키면 a와 nested가 둘 다 나타난다.


def test(a,b):

print(a)

print(b)

def test1(a,b):

print(a+b)

test1(a,b)

test(1,2)

test1(1,2) # ERROR!!

파이썬에서도 같은 일이 가능하다. 파이썬에서는 중첩 정의를 원래부터 허용한다. 물론, test함수의 바깥쪽에서 test1을 불러오려고 하면 오류가 발생한다. 밖에서는 test1이 안 보이기 때문이다. (Scope 문제)

C언어에 GCC를 사용하는 경우에, 함수포인터를 연결해서 함수 내부에 중첩 정의된 함수를 불러오는 것이 가능은 하다. 단, 가능하다고 해서 해도 된다는 뜻은 아니다. 함수는 호출되는 순간에 연결되었다가 끝나는 순간 모든 작동을 정지하므로 만약 중첩 정의된 함수가 함수의 외부에서 호출되었을 때 모든 일을 마무리짓기 전에 바깥쪽의 함수가 끝나버린다면, 일이 마무리되기 전에 종료되어 오류를 발생시킬 것이다. (안해봤음…)


http://langdev.org/posts/38



http://sparrow.borlandforum.com/board/boardview.asp?table_name=tip&sel=&findit=&srch=&gotopage=7&block=0&board_idx=115&path=N&vir_numm=170&vir_numm2=65



http://discuss.joelonsoftware.com/default.asp?interview.11.431470.11



http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html



http://en.wikipedia.org/wiki/Nested_function

코멘트

“함수의 중첩 정의”에 대한 9개 응답

  1. 
                  snowall
                  아바타

    어셈블리어도 공부해봤어요. 컴퓨터과학도 제 전공중 하나니까요. -_-

    그러니까, 제가 하고 싶은 얘기는, 걍 다른 언어를 공부하기 귀찮다는 거예요.

    스페인어, 불어, 라틴어, 일본어, 중국어를 공부하는게 사고의 확장과 영어 공부하는데 도움이 될 수 있겠지만, 그렇다고 그게 그것을 반드시 공부해야만 하는 이유가 되는건 아닙니다. 저는 필요할 때 필요한 언어를 배워서 필요한 만큼만 쓰면 되요.

    단지, 필요한 것을 만드는데 파이썬만큼 삽질한 언어가 없어서 계속 투덜대고 있었을 뿐이죠.

  2. 
                  solariser
                  아바타

    기분이 나빠져도 별수 없네요 ㅋ 어셈블리어는 배워하는 양도 대단히 적고, 복잡한 기능도 전혀 없습니다. 로우 레벨 언어 인 만큼 심플 그자체입니다. 그렇지만, 반대로 CPU가 동작하는 방식 그자체를 표현하고 있기 때문에, CPU의 동작을 이해하는데 큰 도움이 됩니다.

    빠삭하게 알아서 능숙하게 쓸줄알야야 한다는게 아닙니다. 대충 저런게 있고 C와 에셈블리어의 관계가 어떻다 정도는 몇일만 대충 보면 알 수 있습니다. C/C++이 어느정도 선에 도달했다면 바로 이해할 수 있습니다. 그럼에도 하지 않는것은 게으른것이거나, C/C++의 수준이 그정도에 도달하지 않았다는 말밖에 되지 않습니다.

    난 이론 전문가인데? 하는 사람도 어셈을 배워둘 필요가 있습니다. 다른 사람의 작품을 감상하는 기분으로 배워두면 사고의 확장에 크게 도움이 됩니다. 왜나면 기본적인 폰노이만 구조의 한계를 할 수 있습니다…. -_-

  3. 
                  snowall
                  아바타

    저도 프로그램 만들다가 필요하면 쓰겠죠.ㅎㅎ 장점도 단점도 아닌 그냥 특징이라고 봅니다.

    저에게 컴퓨터는 어디까지나 연구 도구일 뿐 연구 대상이 아니라 이것저것 공부하기가 힘드네요. 게다가, 저는 이것저것 하다보면 헷갈려서 효율이 더 떨어져요. 제가 바라는건 딱 하나 배워서 잘 써먹는거지 이것저것 다 잘하는건 아니라서요.

    3번은 어셈블리어 공부 안하고 C/C++만 하는 사람들은 기분이 나빠질 소지가 있는 댓글이네요.

  4. 
                 solariser
                 아바타

    저거 대단히 편리한 기능입니다만… -_-

    1. 저런식으로 써도 별문제 없습니다. 실행파일모델(정확한 용어를 모르겠네요)을 고려해보면 알 수 있습니다. 어떠한 함수를 만들면 변수들의 공간의 제외하고 전부 실행파일에 직접 기록(코드 영역)됩니다. 이부분은 읽기 전용이기 때문에, 동시에 엑서스 하거나, 실행 시점에 따른 문제는 없습니다.(언급된 쓰레드나, 함수 종료에 따른 문제가 발생하지 않습니다.) 변수들은 스텍이나 레지스터에 할당되는데, 함수 실행시 항상 새로 생성되며 서로간에 형향은 없습니다. (쓰레드 실행, 선행 함수의 종료 모두 상관없습니다. static으로 선언하면 달라지지만, 그건 다른 문제이니)

    2. 저런식의 함수 포인터 자체는 뭐 여러가지 용도로 쓰이지만, 일반적으로 클로저(closure)에서 탁월한 효능을을 보입니다.

    클로저가 불가능한 C에서는 OOP를 흉내내거나, 언급한대로 잘난척하는 용도로 씁니다. (코딩 난이도야 다른 문제지만, 일단 이식성이 없어서 쓰면 않됩니다. C의 가장큰 장정이 이식성이니까요) C++은 클로져가 생겼으니 열심히 쓰면 됩니다. ㅋ

    3. 역시 C, C++을 다루는 사람들은 어셉블리어 공부를 좀 해둬야 합니다. 장황하게 ›㎲嗤? 콜링 컨벤션의 구현대한 이해가 있다면, 의문을 가질 여지가 없는 내용입니다.

    4. 다른 프로그래밍 언어를 공부하는게 실력향상에 도움이 됩니다. 언어가 사고의 틀을 결정하는 만큼 하나의 언어만 계속 파면 결국 사고가 경직될수 있습니다. 이런 저런 언어를 꾸준히 공부해 보는게 좋습니다. 중첩 함수는 C, C++, Java에서는 “저건 뭐야!” 수준이지만, JavaScript, Python, Ruby에서는 밥먹듯이 쓰는 겁니다.

    (물론 C에서도 qsort같은 함수 포인터를 받는 함수들이 이미 널리 쓰이고 있고, 콜백용으로 많이 사용되지요, C++에서는 Function Object가 그자리를 담당하고 있어서 완전히 새로운 개념은 아닙니다. )

  5. 
                 goldenbug
                 아바타

    C에서는 그냥 함수명 없이 {}로 코드 일부를 둘러싸면… 그게 함수처럼 작동합니다. 변수가 아주 잠깐 필요할 경우에 쓸 수 있겠지만, 전반적으로는 별로 쓸모는 없죠. ^^

    Lex 님이 말씀하신 것은 초창기에 좋은 프로그램에 대한 인식이 지금과 달랐기 때문입니다. 그때는 남들이 알아보기 힘들게 복잡하게 프로그램을 구축하는 것이 뛰어난 프로그래머이고, 그렇게 만들어진 프로그램이 좋은 프로그램이라고 했었거든요. 이후 코드 재활용과 유지/보수 중요성이 중요하게 여겨지면서 지금처럼 쉽게 코딩하는 것이 좋은 것이라고 바뀌었죠.

  6. 
                  snowall
                  아바타

    저런걸 함수포인터로 엮어서 쓸 정도로 고수인데 동료들 엿먹이는 괴수가 있다는 거군요…-_-;;

    그런 사람이 되지 않도록 테크트리를 잘 올려야겠네요…

  7. 
                Lex
                아바타
    Lex

    솔직히 일하다 보면 변태 같은 사람이 존재합니다. ^^;;

    어찌보면 기본이 덜 되어 있는 사람이라고 볼 수 있는데, 같이 얘기하다보면 ‘벽’이 생깁니다.

    일 하다 사람 치고 싶은 순간이 한 두번이 아닙니다… ^^ㅋ

  8. 
                  snowall
                  아바타

    어차피 중첩정의된 함수를 밖에서 불러오는 것 자체가 삽질이라…

    변태가 아닌 이상 일부러 그런 프로그램을 만들지는 않겠죠…-_-; 유지보수 하는 사람 엿먹으라고 작정하지 않은 이상…

  9. 
                Lex
                아바타
    Lex

    일단 쓰레드를 사용하는게 아니라면 쫑날일은 없습니다.

    C언어류는 전부 Sequential하기 때문에 두 함수가 동시에 실행 되는 경우는 발생하지 않죠. ^^;

    근데, 정말 신기하군요.

    저도 몰랐던 기능입니다.

    물론, 유지보수 측면에서는 절대 써서는 안되는 기능이긴 하지만요. ^^;

Lex 에 응답 남기기응답 취소

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.