인라인 멤버함수의 규칙에 변화가?

ssehoony의 이미지

현재 비졀c++ 2005 를 사용하고 있습니다.
클래스의 맴버함수를 inline 키워드를 이용해서 헤더가아닌 소스파일에서 인라인 함수를 정의했습니다.
그 인라인 멤버함수를 다른 cpp 코드에서 호출하면, 링크에러가 발생하는 군요.
클래스의 맴버함수를 소스파일이 아닌 헤더에서 정의하면 잘 작동하는 군요.

inline 키워드를 이용해 소스에서 정의했을 경우는
외부 파일에서 호출하지는 않고 내부에서만 호출했을 경우에는 링크에러 없이 잘 작동합니다.

제가 알고 있는 기존의 인라인 멤버함수는
헤더에서 구현된 것은 타파일에서도 인라인 확장이 가능하고
소스에서 구현된 것은 동일한 파일에서만 인라인이 확장되고
타파일에서는 그냥 일반 함수콜과 동일하게 작동하는 걸로 알고 있습니다.
다만, 최근 컴파일러의 "전체 프로그램 최적화"라는 옵션을 이용해 타파일의 인라인함수도 확장 가능하게
할 수 있다는 것인데요.
어째 VC++ 2005 의 컴파일러는 그 규칙을 좀 변경해버린 듯 하는군요.

어떻게 된 영문인지 이쪽 사정을 알고 있으시다면 알려주시면 감사하겠습니다.

그리고 하나더...
static 멤버함수는 꼭 헤더에서만 정의해야 하나요?
내부적으로 꼭 그렇게 해야하도록 제한한 이유는 뭔가요?

kewlbear의 이미지

C++98 초안에는 아래와 같이 나와있습니다.

Quote:

An inline function shall be defined in every translation unit in which it is used and shall have exactly the same definition
in every case (3.2).

혹시 실제 표준에서 바뀌지 않았다면 인라인 함수 정의가 헤더 파일에 있어야 하겠군요.
ssehoony의 이미지

넹 그렇군요.
일단 표준대로라면 타파일에서 인라인함수를 사용할려면, 꼭 헤더에 있어야 하겠군요.
기존에 소스에서 정의한 인라인함수를 타파일에서 호출가능했던것은 비표준이었나 보군요.
감사합니다.

static 에 대한건 잘 이해가 안가는군요.
알려주신 내용은 정의에 static 을 붙여라 라는 내용 같은데
이게 꼭 static 멤버 함수는 헤더파일에 있어야 한다는 제약과 어떤 관련이 있는건가요?

그리고 저런 "C++98 초안" 같은 표준안 자료는 어디가면 구할 수 있는건가요?

doldori의 이미지

Quote:
static 에 대한건 잘 이해가 안가는군요.
알려주신 내용은 정의에 static 을 붙여라 라는 내용 같은데
이게 꼭 static 멤버 함수는 헤더파일에 있어야 한다는 제약과 어떤 관련이 있는건가요?

뭔가 오해하신 것 같은데 static member가 반드시 헤더에 정의되어야 하는 것은 아닙니다.
kewlbear님이 인용하신 표준의 내용은 static member는 반드시 클래스 정의 내부에
선언되어야 한다는 것이지 static member의 정의까지 클래스 정의에 있어야 한다는 뜻은 아닙니다.
즉 다음의 형태 모두 가능합니다.
// class definition
class C
{
    static void f();    // declaration
    static void g() { } // definition (and declaration)
    static int i;       // declaration
};
 
// implementation
void C::f() { }  // definition
int C::i;        // definition

다만 const 정수형이 아닌 데이터 멤버의 정의는 반드시 클래스 정의 외부에 존재해야 합니다.

Quote:
그리고 저런 "C++98 초안" 같은 표준안 자료는 어디가면 구할 수 있는건가요?

초안은 ftp://ftp.research.att.com/pub/c++std/WP/CD2/에서 구할 수 있습니다만,
표준과는 유효한 차이가 있습니다. 표준은 ANSI Web Store에서 구입할 수 있고요.
kewlbear의 이미지

마찬가지로 C++98 초안에는 이렇게 나와있습니다.

Quote:

A data or function member of a class may be declared static in a class definition, in which case it is a static member
of the class.

클래스 정의에 멤버 함수를 static으로 선언해야 하는군요.
ted78의 이미지

인라인 함수가 항상 헤더에서 정의되어야 하는 것은 아닙니다.

해당 함수가 사용되는 translation unit에서 odr(one definition rule)만 지켜주면 됩니다.

나는 생각하는 갈대다?

나는 생각하는 갈대다?

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.