'Programming/C++'에 해당되는 글 2건

  1. 2008.12.10 extern "C"
  2. 2008.12.06 C언어와 C++언어의 차이점
Programming/C++2008. 12. 10. 16:14

C와 C++는 컴파일시 obj에 함수 이름, 변수 이름 등의 심벌을 기록하는 방식이 다르다.

그래서 C++ 컴파일러에서 C로 작성된 코드를 컴파일 하고자 할 때 사용한다.

 

C 컴파일러는 함수 이름을 그대로 사용하는 반면 C++ 컴파일러는 그대로 사용하지 않는다.
C++에서 프로그래머가 Func라는 이름으로 함수를 만들어도 이 이름과 동일한 함수를  만들 수 있다.

어떤 Func라는 함수는 정수를 인자로 받고 또 어떤 Func라는 함수는 실수를 인자로 받도록 만들 수 있다.

이렇게 이름이 동일한 여러 개의 함수가 나타날 수 있기 때문에 C++ 컴파일러는 내부적으로 Func라는 이름에다가 인자들의 타입 및 리턴 타입으로 어떤 문자들을 덧붙여서 각 함수들을 구분할 수 있도록 새로운 이름을 만든다.

extern "C"는 C++에서 C 함수를 사용하고자 할 때 컴파일러에게 C 함수라는 것을 알리는 역할을 한다.
이해를 돕기 위해 다음과 같은 프로그램을 예로 들어보자(파일 확장자는 .cpp로 만들어 C++ style로 컴파일한다).
add_1(), fadd_2(), add_3()이 컴파일 된 후 어떻게 이름이 바뀌는지 보면 왜 extern "C" 가 필요한지 알 수 있다.

#include "stdio.h"

int add_1(int a, int b);
float fadd_2(int a, int b);
extern "C" int add_3(int a, int b);

int main()
{
    int a = 2;
    int b = 3;
    int c;
    float fc;

    c  = add_1(a, b);
    fc = fadd_2(a, b);
    c = add_3(a, b);

    return 0;
}

/* -- 시험 삼아 여기를 막는다. --
int add_1(int a, int b)
{
    return a + b;
}

float fadd_2(int a, int b)
{
    return (float)(a + b);
}

int add_3(int a, int b)
{
    return a + b;
}
*/

################### compile/link 결과 ###############################
naver.obj : error LNK2001: unresolved external symbol _add_3
naver.obj : error LNK2001: unresolved external symbol "float __cdecl fadd_2(int, int)" (?fadd_2@@YAMHH@Z)
naver.obj : error LNK2001: unresolved external symbol "int __cdecl add_1(int, int)" (?add_1@@YAHHH@Z)

compile/link하면 위와 같이 link error가 발생한다.
자세히 보면
add_1 -> ?add_1@@YAHHH@Z
fadd_2 -> ?fadd_2@@YAMHH@Z
add_3 -> _add_3
와 같이 compile 과정에서 이름이 바뀐다.
add_1(), fadd_2()는 C++ style의 decorated name으로 바뀐 것이며, add_3()는 prototype에서 extern "C"를 주었으므로 C style로 '_'만 앞에 붙은 것이 차이점이다.

C++는 argument, return value에 따라 이름이 바뀌어 반드시 protype과 일치하는 function이 link된다. argument가 틀린 경우에는 같은 이름의 function이 여러 개 존재할 수 있으며 argument에 따라 적당한 function이 link된다.

C는 단순히 이름 앞에 '_' 만 추가되므로 argument가 틀리던 return value type이 틀리던 link는 될 수 있다. 심하게 잘못되면 compile/link는 되는데 오동작을 할 수도 있다.

C++는 컴파일시 함수 이름을 모두 다른 이름으로 바꿔주기 때문에 C에서 컴파일된 함수를 링크시킬 때는 해당 함수의 선언부 혹은 include 부분에 extern "C"라는 키워드를 사용하여 해당 함수가 C로 컴파일된 함수라는 것을 컴파일러에게 명시적으로 알려줘야 한다.

그런데 이 extern "C" 키워드는 C++에서 사용하는 것이므로 C에서는 사용되지 않는다. 따라서 반대로 C++의 함수를 C에서 사용하고자 한다면 C++ 소스를 컴파일 전에 소스 내에서 사용되는 함수의 선언을 모두
extern "C" 함수선언
이렇게 변환해 주어야 한다.

C에서는 이미 컴파일된 C++ 함수를 호출할 수 없다. 하지만, 만약 이렇게 C++ 소스에서 모든 함수를 extern "C"로 변환한다면 이 함수들은 C++의 함수 특성을 모두 잃게 된다. 즉, 클래스의 멤버 함수가 될 수 없고 인자만 틀리고 함수 이름은 같은 오버로딩 함수가 될 수도 없다.

보통 *.h 파일에 아래와 같이 하여 *.c, *.cpp에서 공용할 수 있는 protype 선언을 한다.

#if defined (__cplusplus)
extern "C" {
#endif

int func1();
int func2();
.
.
.

#if defined (__cplusplus)
};
#endif

참고,
extern "C" aaa();
extern "C" bbb();
는 아래와 같이 블록으로 잡아서 한번만 해주면 된다. 
 
extern "C"
{
    aaa();
    bbb();
}

Posted by skensita
Programming/C++2008. 12. 6. 22:07

1. C언어와 C++언어의 대표적인 차이

- C++은 기존의 C언어 구성요소를 대부분을 사용하며 거기에 진보된 자료형(Data Type)과 객체지향 프로그래밍 개념을 추가
- C++은 C를 기반으로 만들어졌지만 C와 구별되는 독립적인 언어이고, 많은 면에서 C보다 좋은 언어
- C++은 객체지향 언어(Object Oriented Programming)
   프로시쥬어프로그래밍->구조화된 프로그래밍->객체지향프로그래밍
  : 코드와 데이터를 하나로 묶고(코드/데이터 추상화), 이들 서로가 독립성을 지니도록 하는 경향 (모듈화)
- 소프트웨어 산업의 위기 -> 객체지향언어로 극복

 

 

항목

설명

코멘트 스타일에 // 추가

C 언어에서는 // 스트일의 코멘트는 지원하지 않는다.

문자 상수(Character Literal)의 타입

‘a’와 같은 문자 상수를 C언어에서는 int 타입으로 취급하나 C++언어에서는 char 타입으로 취급한다.

sizeof(‘a) == sizeof(int)C언어에서는 true이지만, C++ 언어에서는 그렇지 않다.

문자열 상수의 한정어

C 언어에서 “abc”와 같은 문자열 상수는 char *로 취급되었다. 하지만 C++언어에서는 const char *로 취급한다. 따라서 char *p = exp?”abc” : “de”; C 언어에서는 올바른 구문이지만 C++언어에서는 잘못된 문장이다.

임시 선언(Tentative Declaration)

파일 범위(File Scope) 안에서 int i; int i; 와 같이 i를 두번 선언하는 것은 C언어에서는 허락하지만 C++언어에서는 허락하지 않는다.

struct

C++언어에서 struct는 클래스의 타입으로 취급된다.

파일 범위에서 선언된 명칭

별도의 선언이 없다면 C++언어에서는 내부 연결자(Internal Linkage)를 갖는 것으로 취급되지만 C언어에서는 외부 연결자(External Linkage)를 갖는 것으로 취급된다.

main 함수의 재귀적 호출

C언어에서는 허락되지만 C++언어에서는 허락되지 않는다.

호환되는 타입(Compatible Type)

C언어에서는 허락되지만 C++언어에서는 그렇지 않다. 예를 들어 완전히 동일한 레이아웃을 갖는 struct의 경우 C언어에서는 서로 호환되지만 C++언어에서는 서로 다른 타입일 뿐이다.

void *에서 일반 포인터로의 변환

C언어에서는 암시적인 변환(Implicit Con version)이 가능하지만 C++언어에서는 반드시 명시적으로 변환해야 한다.

암시적 선언(Implicit Declaration)

C언어에서는 함수를 선언하지 않고 사용할 수 있지만, C++언어에서는 그렇지 않다. 참고로, C언어에서 함수를 선언하지 않고 사용하면 함수는 void 타입을 반환하고 매개 변수는 알수 없다는 형태인 빈 괄호 형식으로 선언된다.

Posted by skensita