컴파일 후 링크 시 중복 궁금합니다.

익명 사용자의 이미지

A.h
#ifndef class_A
#define class_A
- class A
- A 멤버 함수로 funcA() (정의도 포함)
#endif

b.cpp
include A.h
funcA() 호출

c.cpp
include A.h
funcA() 호출

위와 같은 구조일때

1)컴파일은 파일단위니깐 b.cpp와 c.cpp를 컴파일 하면 양쪽 오브젝트파일(b.o, c.o) 모두에 class A가 포함되나요??

2)양쪽 모두에 포함된다면 링크 과정에서 먼저 불리는 오브젝트파일의 class A가 심볼로 잡히고 나중에 불리는 오브젝트파일에서 #ifndef로 인해 심볼로 잡히지 않는 건가요??

3)#ifndef, #define 등은 전처리기에서 처리하는 것으로 알고 있는데 링크 시에도 남아있는게 맞나요??

익명 사용자의 이미지

답하기 쉬운 것부터 답하기:

3) 아니요. 안 남아 있습니다.

1) "포함된다"..?는 건 좀 부정확한 표현이지만 대충 느낌만 알아듣자면, 네 맞습니다.

두 파일, 그러니까 정확히는 두 해석 단위(translation unit)는 모두 A.h가 포함하고 있는 클래스 A의 정의, 그리고 클래스 A의 멤버 함수 funcA의 정의를 가지게 됩니다.

2) 이 부분이 가장 답하기 어렵습니다.

- b.cpp에 있는 class A와 c.cpp에 있는 class A는 동일한 클래스입니다. 동일한 줄 알고 씁니다. 양쪽에서 각자 만든 class A 객체를 얼마든지 서로 주고받을 수도 있습니다.
- 그러니 프로그램 전체 입장에서 보면 동일한 클래스에 대해서 두 개의 정의가 있는 셈입니다. C++에서 대개 정의는 유일해야 합니다.
- 그러나 클래스 타입이라던가 열거형 타입이라던가 등에 대해서는 예외적으로 허용이 되는 경우가 있는데, 서로 다른 해석 단위에서 동일한 대상을 정의한 경우입니다. 이 경우 프로그램 전체에 그 정의가 단 하나만 있는 것처럼 취급됩니다.

밑줄 친 부분이 제가 상당히 많은 세부 내용을 날려버리고 대충 정리해 버린 부분입니다. 이 부분에 대한 정확한 설명을 들으시려거든 ODR, 즉 One-definition rule에 대해서 찾아보시면 됩니다.

https://en.cppreference.com/w/cpp/language/definition

컴파일러와 링커가 ODR를 구체적으로 어떻게 준수하는지에 대해서는 제가 설명할 수 있는 영역 밖이네요. 그래도 한 가지 확실하게 말씀드릴 수 있는 것은, #ifndef는 아닙니다. #ifndef는 전처리 단계에서 사라지거든요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.