일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 컴퓨터과학
- 네트워크
- 데이터과학
- 데이터베이스
- 네트워크보안
- 코딩
- 소프트웨어
- 프로그래밍언어
- 딥러닝
- 컴퓨터공학
- 파이썬
- 웹개발
- 빅데이터
- 클라우드컴퓨팅
- 보안
- 자료구조
- 자바스크립트
- 인공지능
- 알고리즘
- 소프트웨어공학
- 데이터구조
- 버전관리
- I'm Sorry
- 컴퓨터비전
- 머신러닝
- 사이버보안
- 프로그래밍
- 2
- Yes
- 데이터분석
- Today
- Total
스택큐힙리스트
"extern 'C'"는 함수 선언에서만 필요한가요? 본문
나는 C 프로그램에서 호출해야 하는 C++ 함수를 작성했습니다. C에서 호출 가능하게 하기 위해 함수 선언에 extern C
를 지정했습니다. 그런 다음 C++ 코드를 컴파일했지만, 컴파일러(Dignus Systems/C++)가 함수에 대해 이름 맹글링을 생성했습니다. 따라서, extern C
를 준수하지 않은 것 같습니다.
이를 해결하기 위해 함수 정의에 extern C
를 추가했습니다. 이후 컴파일러는 C에서 호출 가능한 함수 이름을 생성했습니다.
기술적으로는 extern C
는 함수 선언에서만 지정해야 합니다. 맞습니까? (이에 대한 좋은 예시는 C++ FAQ에 있습니다.) 함수 정의에서도 지정해야 할까요?
다음은 이를 설명하는 예시입니다:
/* ---------- */
/* foo.h */
/* ---------- */
#ifdef __cplusplus
extern C {
#endif
/* 함수 선언 */
void foo(int);
#ifdef __cplusplus
}
#endif
/* ---------- */
/* foo.cpp */
/* ---------- */
#include foo.h
/* 함수 정의 */
extern C // <---- 이게 필요한가요?
void foo(int i) {
// 무언가를 수행합니다...
}
내 문제는 잘못된 코딩 때문인지 컴파일러 버그를 발견했는지 모르겠습니다. 어쨌든 올바른 방법이 무엇인지 정확히 알기 위해 stackoverflow를 참고하려고합니다.
답변 1
'extern C
' 함수 정의에 필요하지 않습니다. 단지 이전에 존재하는 선언에 포함되었다면 말입니다. 표준에 명시된 것처럼(7.5/5 링크 지정):
명시적인 링크 지정 뒤에 링크 지정 없이 함수를 선언할 수 있으며, 이전 선언에서 명시적으로 지정된 링크는 이러한 함수 선언에 영향을 주지 않습니다.
하지만 저는 일반적으로 정의에도 'extern C
'를 추가합니다. 왜냐하면 실제로 extern C 링크의 함수이기 때문입니다. 많은 사람들은 불필요하고 중복된 선언을 싫어합니다 (예: 메서드 오버라이드에 virtual
을 넣는 것). 하지만 저는 그중 하나가 아닙니다.
답변 2
'extern C 정의 요건은 함수 선언부에만 필요한가요?''extern C를 사용하는 것은 어떤 의미가 있을까요?'라는 주제에 대해 SEO 지향적인 한국어 글을 작성해보겠습니다.
---
C++에서는 C 언어와의 호환성을 유지하기 위해 extern C 지시어를 사용할 수 있습니다. 이는 컴파일러에게 해당 함수를 C 스타일의 함수로 취급하도록 지시하는 역할을 합니다. 하지만 extern C 정의 요건은 메소드 선언뿐만 아니라 정의 부분에도 필요하다는 점을 알아두시기 바랍니다.
extern C는 주로 C++로 작성된 코드와 C로 작성된 코드를 혼합하여 사용해야하는 경우에 자주 쓰입니다. C 언어는 많은 하드웨어 플랫폼에서 사용되고 있으며, C++ 코드와의 호환성을 제공하는 방법 중 하나입니다.
C 언어는 컴파일러가 함수를 호출할 때 네임 맹글링(name mangling)을 하지 않으며, 컴파일된 코드에서 함수 이름은 그대로 유지됩니다. 반면, C++에서는 명시적인 함수 오버로딩 등의 기능을 제공하기 위해 함수 이름을 변경하는 네임 맹글링을 수행합니다. 이로 인해 C++ 코드에서 선언한 함수는 네임 맹글링된 형태로 컴파일되어 실제 C 코드에서 호출할 때 문제가 발생할 수 있습니다.
이를 해결하기 위해 extern C를 사용하면 해당 함수는 C 스타일의 함수로 간주되어 네임 맹글링 과정이 생략되거나 컴파일러에 의해 C 스타일로 변환됩니다. 이를 통해 C++ 코드에서 선언한 함수를 C 코드에서 호출할 때, 함수 이름과 매개변수가 정확히 일치하도록 보장할 수 있습니다.
하지만 extern C 지시어는 함수의 선언뿐만 아니라 정의 부분에도 필요합니다. 왜냐하면 함수 정의는 함수의 몸체를 포함하고 있으므로 컴파일러에게 다른 매개변수 또는 호출 규칙을 적용하지 않도록 하기 위함입니다. 함수 선언은 함수 이름과 시그니처만을 가지고 있지만, 함수 정의는 명령어들을 포함하고 있어서 C++ 컴파일러가 네임 맹글링을 수행하기 때문입니다.
따라서 extern C 정의 요건은 함수 선언뿐만 아니라 정의 부분에도 필요합니다. 정의 부분을 제외하고 extern C를 사용한다면, C++ 컴파일러는 해당 함수의 네임 맹글링을 수행하고, C 코드에서 호출할 때 문제가 발생할 수 있습니다. 따라서 호환성을 보장하고 C++ 코드와 C 코드를 혼합하여 사용하려면, 함수 선언과 정의 부분 모두에 extern C를 명시해야 합니다.
여기서 확인해야 할 중요한 점은 extern C를 사용하는 것이 C++ 코드의 실행 성능을 희생시키지 않는다는 것입니다. 다만 네임 맹글링이 수행되지 않기 때문에, 외부 라이브러리를 사용하는 경우에는 해당 라이브러리가 C 스타일의 인터페이스를 제공해야만 호환성을 유지할 수 있습니다.
결론적으로, extern C 지시어는 C++ 코드와 C 코드를 함께 사용할 때 호환성을 보장하기 위해 사용됩니다. C++ 코드의 함수 선언과 정의 부분 모두에 extern C를 명시해야만 C 스타일의 함수로 취급되며, 컴파일러에 의한 네임 맹글링 과정을 생략할 수 있습니다. 이를 통해 C++ 코드와 C 코드를 혼합하여 사용할 때 발생할 수 있는 호환성 관련 문제를 방지할 수 있습니다.