명품 C++ 13장 예외 처리와 C 언어와의 링크 지정.

Slides:



Advertisements
Similar presentations
12 장 템플릿 (template) Sung-Min Jung Internet Management Technology Lab. School of Information & Communication Engineering, Sungkyunkwan Univ. 300 Cheoncheon-dong,
Advertisements

명품 JAVA Programming 제 3 장 반복문, 배열, 예외처리.
Vision System Lab, Sang-Hun Han
명품 C++ 프로그래밍 3장. 클래스와 객체.
명품 C++ 8장 상속.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
명품 C++ 4장. 객체 포인터와 객체 배열, 객체의 동적 생성.
Power C++ 제6장 포인터와 문자열.
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제3장 배열과 포인터.
2장 닷넷 프레임워크.
C++ Espresso 제1장 기초 사항.
IntArray[0] int length 5 intArray 객체 제 3 장 반복문, 배열, 예외처리.
C++ Espresso 제2장 제어문과 함수.
강좌명 : C++프로그래밍 (C++ Programming)
제 12장 예외 처리 12.1 설계 쟁점 12.2 PL/I의 ON-조건 12.3 Ada의 예외 처리
실전 프로젝트 2 : 숫자야구 숫자 야구를 구현해보자.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
제6장 객체배열과 벡터 객체 배열을 이해한다. 벡터(vector) 클래스를 사용할 수 있다.
Chapter 11 – 예외 처리 Outline 11.1 설계 쟁점 11.2 Pl/I의 예외 처리 11.3 Ada의 예외 처리
10장 예외 처리 프로그래밍 언어론 10.6 Pascal과 C의 에러 처리 10.1 설계 주제 10.2 PL/I의 예외 처리
C++ Exspresso 제5장 클래스의 기초.
8. 객체와 클래스 (기본).
제7장 제어구조 I – 식과 문장.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
C++ Espresso 제9장 다형성.
JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심.
7 스택.
10장 템플릿과 표준 템플릿 라이브러리(STL)
배열, 포인터, 참조 배열은 같은 형을 가지는 변수들의 묶음이다..
명품 C++ 8장 상속.
Choi, Namseok Java 기초 (Java의 제어문과 배열) Choi, Namseok
명품 Java Programming.
명품 C++ 7장 프렌드와 연산자 중복.
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
14장. 함수 1 01_ 함수의 기본 02_ 인자의 전달.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
C ++ 프로그래밍 시작.
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
스택(Stack) 김진수
프로그램과 데이터의 구조화 Organizing programs and data
17장. 문자열 01_ 문자열 사용의 기본 02_ 문자열의 사용.
14. 예외처리.
자바 5.0 프로그래밍.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
제14장 예외처리와 템플릿 예외 처리의 개요를 학습한다. 예외 처리를 적용할 수 있다. 템플릿의 개념을 이해한다.
제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
타입, 연산자 Chapter 5, 6 Kum Deuk Kyu , Ph. D. Spring 2015
가상함수와 추상 클래스.
Chapter 1 C와는 다른 C++. 최호성.
제2장 제어구조와 배열 if-else 문에 대하여 학습한다. 중첩 if-else 문에 대하여 학습한다.
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
4. 고급변수 사용 : 포인터와 관련하여 메모리 바라보기
컴퓨터공학실습(I) 3주 인공지능연구실.
루프와 카운트 Looping and counting
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
Java 3장. 자바의 기본 구조 I : 변수, 자료형, 연산자 public class SumTest {
5. 논리적 자료표현 : 구조체.
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
JVM의 구조와 메모리 모델 JVM의 내부 구조 클래스 파일 클래스 로더 메소드(method) 영역 힙(heap) 영역
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
포인터와 배열 조 병 규 한 국 교 통 대 학 교 SQ Lab..
C# 10장. 참조형.
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
10장 템플릿과 표준 템플릿 라이브러리(STL)
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
배열, 포인터, 함수 Review & 과제 1, 2.
Presentation transcript:

명품 C++ 13장 예외 처리와 C 언어와의 링크 지정

실행 오류의 종류와 원인 오류 컴파일 오류 실행 오류 문법에 맞지 않는 구문으로 인한 오류 개발자의 논리 오류 예외적으로 발생하는 입력이나 상황에 대한 대처가 없을 때 발생하는 오류 실행 오류의 결과 결과가 틀리거나 엉뚱한 코드 실행, 프로그램이 비정상 종료

예제 13-1 예외 상황에 대한 대처가 없는 프로그램 사례 밑수와 지수부를 매개 변수로 지수 값을 계산하는 함수를 작성하는 사례이다. #include <iostream> using namespace std; int getExp(int base, int exp) { // base의 exp 지수승을 계산하여 리턴 int value=1; for(int n=0; n<exp; n++) value = value * base; // base를 exp번 곱하여 지수 값 계산 return value; } int main() { int v= getExp(2, 3); // 2의 3승 = 8 cout << "2의 3승은 " << v << "입니다." << endl; int e = getExp(2, -3); // 2의 -3승은 ? cout << "2의 -3승은 " << e << "입니다." << endl; 예상치 못한 음수 입력에 대한 대처가 없는 부실한 코드! 오답! 23은 -1이 아니라 1/8 2의 3승은 8입니다. 2의 -3승은 1입니다.

getExp()의 리턴 값이 오류 상태와 계산 값을 함께 표시하는 예민한 예제 13-2 if문과 리턴 값을 이용한 오류 처리 #include <iostream> using namespace std; int getExp(int base, int exp) { if(base <= 0 || exp <= 0) { return -1; // 오류 리턴 } int value=1; for(int n=0; n<exp; n++) value = value * base; return value; int main() { int v=0; v = getExp(2, 3); if(v != -1) cout << "2의 3승은 " << v << "입니다." << endl; else cout << "오류. 2의 3승은 " << "계산할 수 없습니다." << endl; int e=0; e = getExp(2, -3); // 2의 -3 승 ? getExp()는 false 리턴 if(e != -1) cout << "2의 -3승은 " << e << "입니다." << endl; cout << "오류. 2의 -3승은 " << "계산할 수 없습니다." << endl; 음수 입력에 대한 대처 있음 매개 변수 중 하나라도 음수이면 -1을 리턴한다. getExp()의 리턴 값이 오류 상태와 계산 값을 함께 표시하는 예민한 코드! 2의 3승은 8입니다. 오류. 2의 -3승은 계산할 수 없습니다.

예제 13-3 리턴 값과 참조 매개 변수를 이용한 오류 처리 #include <iostream> using namespace std; bool getExp(int base, int exp, int &ret) { // baseexp 값을 계산하여 ret에 저장 if(base <= 0 || exp <= 0) { return false; } int value=1; for(int n=0; n<exp; n++) value = value * base; ret = value; return true; int main() { int v=0; if(getExp(2, 3, v)) // v = 23 = 8. getExp()는 true 리턴 cout << "2의 3승은 " << v << "입니다." << endl; else cout << " 오류. 2의 3승은 " << "계산할 수 없습니다." << endl; int e=0; if(getExp(2, -3, e)) // 2-3 ? getExp()는 false 리턴 cout << "2의 -3승은 " << e << "입니다." << endl; cout << "오류. 2의 -3승은 " << "계산할 수 없습니다." << endl; 참조 매개 변수 음수 입력에 대한 대처 있음 getExp()의 리턴 값의 단일화 - 오류 상태만 표시 참조 매개 변수를 통해 계산 값을 전달하는 정리된 코드! 2의 3승은 8입니다. 오류. 2의 -3승은 계산할 수 없습니다.

예외 예외란? 예외 처리기 예외 처리 수준 실행 중, 프로그램 오동작이나 결과에 영향을 미치는 예상치 못한 상황 발생 예) getExp() 함수에 예상치 못하게 사용자가 음수를 입력하여 2-3을 1로 계산한 경우 예외 처리기 예외 발생을 탐지하고 예외를 처리하는 코드 잘못된 결과, 비정상적인 실행, 시스템에 의한 강제 종료를 막음 예외 처리 수준 운영체제 수준 예외 처리 운영체제가 예외의 발생을 탐지하여 응용프로그램에게 알려주어 예외에 대처하게 하는 방식 운영체제마다 서로 다르므로, 운영체제나 컴파일러 별로 예외 처리 라이브러리로 작성 Java 경우, JVM 혹은 라이브러리에서 탐지한 예외를 자바응용프로그램에게 전달 윈도우 운영체제는 탐지한 예외를 C/C++ 응용프로그램에게 알려줌 운영체제와 컴파일러 의존적인 C++ 문법 사용 응용프로그램 수준 예외 처리 사용자의 잘못된 입력이나 없는 파일을 여는 등 응용프로그램 수준에서 발생하는 예외를 자체적 으로 탐지하고 처리하는 방법 C++ 예외 처리 C++ 표준의 예외 처리 이 책에서 다루는 내용

피자 자동 기계와 예외 처리개념 예외 자동 피자 기계 예외 처리 우연찮게 끼어 있는 이물질 이물질 분리 처리기 이물질만 분리되어 처리됨 정상적으로 만들어진 피자. 자동 피자 기계 예외 예외 처리

C++ 예외 처리 기본 형식 try-throw-catch try { } 블록 throw 문 catch() { } 블록 예외가 발생할 가능성이 있는 코드를 묶음 throw 문 발견된 예외를 처리하기 위해, 예외 발생을 알리는 문장 try { } 블록 내에서 이루어져야 함 catch() { } 블록 throw에 의해 발생한 예외를 처리하는 코드 try { // 예외가 발생할 가능성이 있는 실행문. try {} 블록 .............................................................. 예외를 발견한다면 { throw XXX; // 예외 발생을 알림. XXX는 예외 값 } throw YYY; // 예외 발생을 알림. YYY는 예외 값 catch(처리할 예외 파라미터 선언) { // catch { } 블록 예외 처리문

throw와 catch throw 3 ; // int 타입의 값 3을 예외로 던짐 ... catch( int x ) { // throw 3;이 실행되면 catch() 문 실행. x에 3이 전달 } 예외 타입 매개변수 try { throw 3.5; // double 타입의 예외 던지기 } catch(double d) { // double 타입 예외 처리. 3.5가 d에 전달됨 ... try { throw “음수 불가능”; // char* 타입의 예외 던지기 } catch(char* s) { // char* 타입의 예외 처리. 예외 값은 “음수 불가능”이 s에 전달됨 cout << s; // “음수 불가능” 출력

try-throw-catch의 예외 처리 과정 n n 5 sum sum 15 15 try { if(n == 0) throw n; else { average = sum / n; ..... } catch(int x) { cout << "예외 발생!! "; cout << x << "으로 나눌 수 없음" << endl; average = 0; cout << "평균 = " << average << endl; try { if(n == 0) throw n; else { average = sum / n; ..... } catch(int x) { cout << "예외 발생!! "; cout << x << "으로 나눌 수 없음" << endl; average = 0; cout << "평균 = " << average << endl; 오류 탐지 코드 예외 발생. n을 x에 전달 예외 처리 코드 x 평균 = 3 예외 발생!! 0으로 나눌 수 없음 평균 = 0 (a) 예외가 발생하지 않은 경우 (b) 예외가 발생한 경우

예제 13-4 0으로 나누는 예외 처리 합과 인원수를 입력 받아 평균을 내는 코드에, 인원수가 0이거나 음수가 입력되는 경우 예외 처리하는 프로그램을 작성하라. #include <iostream> using namespace std; int main() { int n, sum, average; while(true) { cout << "합을 입력하세요>>"; cin >> sum; cout << "인원수를 입력하세요>>"; cin >> n; try { if(n <= 0) // 오류 탐지 throw n; // 예외 발생. catch(int x) 블록으로 점프 else average = sum / n; } catch(int x) { cout << "예외 발생!! " << x << "으로 나눌 수 없음" << endl; average = 0; cout << endl; continue; cout << "평균 = " << average << endl << endl; // 평균 출력 합을 입력하세요>>15 인원수를 입력하세요>>5 평균 = 3 합을 입력하세요>>12 인원수를 입력하세요>>-3 예외 발생!! -3으로 나눌 수 없음 합을 입력하세요>>25 인원수를 입력하세요>>0 예외 발생!! 0으로 나눌 수 없음 합을 입력하세요>>

throw와 catch의 예 하나의 try { } 블록에 다수의 catch() { } 블록 연결 ... throw "음수 불가능"; throw 3; } catch(char* s) { // 문자열 타입의 예외 처리. “음수 불가능” 이 s에 전달 catch(int x) { // int 타입 예외 처리. 3이 x에 전달됨 int main() { try { int n = multiply(2, -3); cout << "곱은 " << n << endl; } catch(char* negative) { cout << "exception happened : " << negative; 함수 호출 int multiply(int x, int y) { if(x < 0 || y < 0) throw "음수 불가능"; else return x*y; } exception happened : 음수 불가능 예외 던지기

예제 13-5 지수 승 계산을 예외 처리 코드로 재작성(완결판) 예제 13-1, 13-3, 13-3의 오류 처리 코드를 try-throw-catch 블록을 이용한 예외 처리 방식으로 작성하라. #include <iostream> using namespace std; int getExp(int base, int exp) { if(base <= 0 || exp <= 0) { throw "음수 사용 불가"; } int value=1; for(int n=0; n<exp; n++) value = value * base; return value; // 계산 결과 리턴 int main() { int v=0; try { v = getExp(2, 3); // v = 2의 3승 = 8 cout << "2의 3승은 " << v << "입니다." << endl; v = getExp(2, -3); // 2의 -3 승 ? cout << "2의 -3승은 " << v << "입니다." << endl; catch(char *s) { cout << s << endl; 예외 발생 2의 3승은 8입니다. 예외 발생 !! 음수 사용 불가

예제 13–6 문자열을 정수로 변환하기 문자열을 정수로 변환하는 프로그램을 작성하라. 정수로 변환할 수 없는 문자열의 경우 #include <iostream> #include <cstring> using namespace std; // 문자열을 정수로 변환하여 리턴 // 정수로 변환하기 어려운 문자열의 경우, char* 타입 예외 발생 int stringToInt(char x[]) { int sum = 0; int len = strlen(x); for(int i=0; i<len; i++) { if(x[i] >= '0' && x[i] <= '9') sum = sum*10 + x[i]-'0'; else throw x; // char* 타입의 예외 발생 } return sum; int main() { int n; try { n = stringToInt("123"); // 문자열을 정수로 변환 cout << "\"123\" 은 정수 " << n << "로 변환됨" << endl; n = stringToInt("1A3"); // 문자열을 정수로 변환 cout << "\"1A3\" 은 정수 " << n << "로 변환됨" << endl; catch(char* s) { cout << s << "처리에서 예외 발생!!" << endl; return 0; 문자열을 정수로 변환하는 프로그램을 작성하라. 정수로 변환할 수 없는 문자열의 경우 예외 처리하라. 예외 발생 "123" 은 정수 123로 변환됨 1A3 처리에서 예외 발생!!

예외를 발생시키는 함수의 선언 예외를 발생시키는 함수는 다음과 같이 선언 가능 함수 원형에 연이어 throw(예외 타입, 예외 타입, ...) 선언 장점 프로그램의 작동을 명확히 함 프로그램의 가독성 높임 int max(int x, int y) throw(int) { if(x < 0) throw x; else if(y < 0) throw y; else if(x > y) return x; else return y; } 모두 int 타입 예외 발생 double valueAt(double *p, int index) throw(int, char*) { if(index < 0) throw "index out of bounds exception"; else if(p == NULL) throw 0; else return p[index]; } char* 타입 예외 발생 int 타입 예외 발생

예제 13-7 예외 처리를 가진 스택 클래스 만들기 Main.cpp MyStack.h MyStack.cpp 200 100 #ifndef MYSTACK_H #define MTSTACK_H class MyStack { int data[100]; int tos; public: MyStack() { tos = -1; } void push(int n) throw(char*); int pop() throw(char*); }; #endif #include <iostream> using namespace std; #include "MyStack.h" int main() { MyStack intStack; try { intStack.push(100); // 푸시 100 intStack.push(200); // 푸시 200 cout << intStack.pop() << endl; // 팝 200 cout << intStack.pop() << endl; // 팝 100 cout << intStack.pop() << endl; // "Stack Empty" 예외 발생 } catch(char* s) { cout << "예외 발생 : " << s << endl; MyStack.cpp #include "MyStack.h" void MyStack::push(int n) { if(tos == 99) throw "Stack Full"; tos++; data[tos] = n; } int MyStack::pop() { if(tos == -1) throw "Stack Empty"; int rData = data[tos--]; return rData; 200 100 예외 발생 : Stack Empty 3 번째 pop() 에서 예외 발생

다중 try { } 블록 try { } 블록 내에 try { } 블록의 중첩 가능 try { ... throw 3; throw "abc"; throw 5; } catch(int inner) { cout << inner; // 5 출력 catch(char* s) { cout << s; // "abc“ 출력 catch(int outer) { cout << outer; // 3 출력 try 블록에 연결된 catch 블록으로 점프 바깥 try 블록에 연결된 catch 블록으로 점프

throw 사용 시 주의 사항 throw 문의 위치 예외를 처리할 catch()가 없으 면 프로그램 강제 종료 try { ... } catch(int n) { throw 문의 위치 항상 try { } 블록 안에서 실행 되어야 함 시스템이 abort() 호출, 강제 종 료 예외를 처리할 catch()가 없으 면 프로그램 강제 종료 catch() { } 블록 내에도 try { } catch() { } 블록 선언 가능 try { throw "aa"; // char* 타입의 예외를 처리할 // catch() { } 블록이 없기 때문에 // 프로그램 종료 } catch(double p) { ... try { throw 3; } catch(int x) { throw "aa"; // 아래의 catch(char* p) { } // 블록에서 처리된다. catch(char* p) { ...

예외 클래스 만들기 예외 값의 종류 예외 클래스 기본 타입의 예외 값 객체 예외 값 정수, 실수, 문자열 등 비교적 간단한 예외 정보 전달 객체 예외 값 예외 값으로 객체를 던질 수 있다. 예외 값으로 사용할 예외 클래스 작성 필요 예외 클래스 사용자는 자신 만의 예외 정보를 포함하는 클래스 작성 throw로 객체를 던짐 객체가 복사되어 예외 파라미터에 전달

예제 13-8 예외 클래스 만들기 두 양수를 입력 받아 나누기한 결과를 출력하는 프로그램에, 음수가 입력된 경우와 0으로 나누기가 발생하는 경우, 예외를 처리하도록 예외 클래스를 작성하라 #include <iostream> #include <string> using namespace std; class MyException { // 사용자가 만드는 기본 예외 클래스 선언 int lineNo; string func, msg; public: MyException(int n, string f, string m) { lineNo = n; func = f; msg = m; } void print() { cout << func << ":" << lineNo << " ," << msg << endl; } }; class DivideByZeroException : public MyException { // 0으로 나누는 예외 클래스 선언 DivideByZeroException(int lineNo, string func, string msg) : MyException(lineNo, func, msg) { } class InvalidInputException : public MyException { // 잘못된 입력 예외 클래스 선언 InvalidInputException(int lineNo, string func, string msg) int main() { int x, y; try { cout << "나눗셈을 합니다. 두 개의 양의 정수를 입력하세요>>"; cin >> x >> y; if(x < 0 || y < 0) throw InvalidInputException(32, "main()", "음수 입력 예외 발생"); if(y == 0) throw DivideByZeroException(34, "main()", "0으로 나누는 예외 발생"); cout << (double)x / (double)y; } catch(DivideByZeroException &e) { e.print(); catch(InvalidInputException &e) { 나눗셈을 합니다. 두 개의 양의 정수를 입력하세요>>2 5 0.4 나눗셈을 합니다. 두 개의 양의 정수를 입력하세요>>200 -3 main():32 ,음수 입력 예외 발생 나눗셈을 합니다. 두 개의 양의 정수를 입력하세요>>20 0 main():34 ,0으로 나누는 예외 발생

C++ 코드에서 C 코드의 링킹 이름 규칙(naming mangling) C 언어의 이름 규칙 C++의 이름 규칙 컴파일 후 목적 코드에 이름 붙이는 규칙 변수, 함수, 클래스 등의 이름 C 언어의 이름 규칙 함수 이름 앞에 밑줄표시문자(_)를 붙인다. int f(int x, int y) ----> _f int main() ----------> _main C++의 이름 규칙 함수의 매개 변수 타입과 개수, 리턴 타입에 따라 복잡한 이름 int f(int x, int y) ----> ?f@@YAHHH@Z int f(int x) ----> ?f@@YAXH@Z int f() ----> ?f@@YAHXZ int main() ----> _main

C 프로그램의 컴파일과 링킹  int f(int x, int y); int main() { f(2, 5); } return x + y; } f.c main.c C 컴파일 C 컴파일 함수 f에 대한 링킹 성공 _main { _f } _f { .... } f.obj main.obj 링킹  main.exe

C++ 소스의 컴파일과 링킹  int f(int x, int y); int main() { f(2, 5); } return x + y; } f.cpp main.cpp C++ 컴파일 C++ 컴파일 함수 f에 대한 링킹 성공 _main { ?f@@YAHHH@Z } ?f@@YAHHH@Z { .... } f.obj main.obj 링킹  main.exe

C++에서 C 함수 호출 시 링크 오류 발생 #include <iostream> using namespace std; int f(int x, int y); int main() { int n = f(2, 5); cout << n; } int f(int x, int y) { return x + y; } f.c C 컴파일 main.cpp C++ 컴파일 함수 f에 대한 링킹 실패 _main { ?f@@YAHHH@Z …. } _f { .... } f.obj main.obj 링킹 실패 main.exe

_main 함수에 있는 ?f@@YAHHH@Z 이름의 함수를 찾을 수 없다는 뜻 비주얼 C++에서의 링크 오류 메시지 f.c main.cpp컴파일 성공 _main 함수에 있는 ?f@@YAHHH@Z 이름의 함수를 찾을 수 없다는 뜻 1>------ 빌드 시작: 프로젝트: LinkError, 구성: Debug Win32 ------ 1> f.c 1> main.cpp 1>main.obj : error LNK2019: "int __cdecl f(int,int)" (?f@@YAHHH@Z) 외부 기호(참조 위치: _main 함수)에서 확인하지 못했습니다. 1>C:\C++\chap13\ExceptionAverage\Debug\LinkError.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다. ========== 빌드: 성공 0, 실패 1, 최신 0, 생략 0 ========== 링크 실패

extern “c” extern “c” 사용법 C 컴파일러로 컴파일할 것을 지시 함수 하나만 선언 여러 함수들 선언 헤더파일 통째로 선언 extern "C" int f(int x, int y); extern "C" { int f(int x, int y); void g(); char s(int []); } extern "C" { #include "mycfunction.h" }

extern “C”를 이용하여 링크 성공  #include <iostream> using namespace std; int g(int x, int y); extern "C" int f(int x, int y); int main() { cout << f(2, 5) << endl; cout << g(2, 5) << endl; } int f(int x, int y) { return x + y; } int g(int x, int y) { return x - y; } f.c g.cpp 7 -3 C 컴파일 C++ 컴파일 main.cpp C++ 컴파일 함수 f에 대한 링킹 성공 함수 g에 대한 링킹 성공 _main { _f ?g@@YAHHH@Z } _f { .... } ?g@@YAHHH@Z { .... } f.obj g.obj main.obj 링킹 성공  main.exe