Bug 247167

Summary: "undefined reference" error from g++ for private class variables.
Product: [Fedora] Fedora Reporter: Bob Goates <rrgoates>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 6   
Target Milestone: ---   
Target Release: ---   
Hardware: athlon   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-07-06 19:05:02 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Bob Goates 2007-07-05 18:57:45 UTC
Description of problem:  g++ and/or ld report "undefined reference" error when
processing private class variables (i.e., static variables in the private part
of a class).

Version-Release number of selected component (if applicable):
Package is gcc-4.1.2-13.fc6.src.rpm, g++ reports version as "g++ (GCC) 4.1.2
20070626 (Red Hat 4.1.2-13)".

How reproducible:  Can be reproduced with the following program, t.cpp:
#include <iostream>

class A
{
public:
        void setStr(char * strIn) { privStr = strIn; }
        void dump() { std::cout << "privStr = \"" << privStr << "\"\n"; }

private:
        static char * privStr;
};


int main(int argc, char ** argv)
{
        A * a = new A();

        a->setStr("new value");
        a->dump();
}


Steps to Reproduce:
1. g++ t.cpp -o t
2.
3.
  
Actual results:
/tmp/ccRpYHoY.o: In function `A::setStr(char*)':
t.cpp:(.text._ZN1A6setStrEPc[A::setStr(char*)]+0x13): undefined reference to
`A::privStr'
/tmp/ccRpYHoY.o: In function `A::dump()':
t.cpp:(.text._ZN1A4dumpEv[A::dump()]+0x10): undefined reference to `A::privStr'
collect2: ld returned 1 exit status


Expected results:
Successful compilation and creation of an executable file.

Additional info:  This problem also occurs with the latest g++ supplied by and
running on gentoo on an athlon.

Comment 1 Jakub Jelinek 2007-07-06 19:05:02 UTC
Please study ISO C++98, [class.static.data]/2:
"The declaration of a static data member in its class definition is not a
definition and may be of an incomplete type other than cv-qualified void. The
definition for a static data member shall appear in a namespace scope enclosing
the member's class definition. In the definition at namespace scope, the name of
the static data member shall be qualified by its class name using the ::
operator. The initializer expression in the definition of a static data member
is in the scope of its class (3.3.6). [Example:
        class process {
                  static process* run_chain;
                  static process* running;
        };
        process* process::running = get_main();
        process* process::run_chain = running;
The static data member run_chain of class process is defined in global scope;
the notation process::run_chain specifies that the member run_chain is a member
of class process and in the scope of class process. In the static data member
definition, the initializer expression refers to the static data member running
of class process. ]
"
In particular, you get the undefined reference because you forgot to define the
static data member variable.

Comment 2 Bob Goates 2007-07-06 21:54:54 UTC
You a correct, of course.  My apologies.