public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/45082]  New: Static const signed int class member causes undefined symbol.
@ 2010-07-26 15:25 rwitmer at xmission dot com
  2010-07-26 15:32 ` [Bug c++/45082] " jakub at gcc dot gnu dot org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: rwitmer at xmission dot com @ 2010-07-26 15:25 UTC (permalink / raw)
  To: gcc-bugs

A class that has a static const signed int data member when passed to a
function as a const int& parameter will cause the data member to be an
undefined symbol.  If the static const signed int data member is re-typed as
const unsigned int the error goes away.  I've verified this on g++ 3.4.6 and
4.1.2. The following code example illustrates the error.

#include <stdio.h>

static const signed int GLOBAL_BUFF_SIZE=30;

class myclass
{
  public:

    static const          int BUFF_SIZE = 20;  // Causes linker error.
  //static const   signed int BUFF_SIZE = 20;  // Causes linker error.
  //static const unsigned int BUFF_SIZE = 20;  // No     linker error.

    static const          int ANOTHER_BUFF_SIZE;

    int myArray[BUFF_SIZE];

/*  Linker error.
% g++ static2.cpp
Undefined                       first referenced
 symbol                             in file
myclass::BUFF_SIZE                  /var/tmp//cc2IHYwP.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status
% g++ --version
g++ (GCC) 3.4.6
and
g++ (GCC) 4.1.2
% ccppc --version                            
ccppc (Wind River VxWorks G++ DWARF-EH 4.1-131) 4.1.2
*/
};

// This solves the linker problem.  
// Not an option for me.  I need to dimension an array with BUFF_SIZE.
const int myclass::ANOTHER_BUFF_SIZE=20;

// Function that takes a constant reference to an integer.
// When a static const signed int is passed to this function
// that was defined in a class, you get the linker error.
// If that static const is declared unsigned int, you dont get the error.
// When the reference is to a global static, there is no error.
void funky(const int& in)
{
  printf("What came into funky() was %d\n", in);
}

int main()
{
  printf("%d\n", myclass::BUFF_SIZE);  // This doesn't cause the error.
  funky(myclass::BUFF_SIZE);           // This line causes the error.
  funky(myclass::ANOTHER_BUFF_SIZE);   // This doesn't cause the error.
  funky(GLOBAL_BUFF_SIZE);             // This doesn't cause the error.
}


-- 
           Summary: Static const signed int class member causes undefined
                    symbol.
           Product: gcc
           Version: 4.1.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rwitmer at xmission dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c++/45082] Static const signed int class member causes undefined symbol.
  2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
@ 2010-07-26 15:32 ` jakub at gcc dot gnu dot org
  2010-07-26 15:59 ` rwitmer at xmission dot com
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu dot org @ 2010-07-26 15:32 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from jakub at gcc dot gnu dot org  2010-07-26 15:32 -------
This is not valid C++.  See [class.static.data]/4:
If a static data member is of const integral or const enumeration type, its
declaration in the class definition can specify a constant-initializer which
shall be an integral constant expression (5.19). In that case, the member can
appear in integral constant expressions within its scope. The member shall
still be defined in a namespace scope if it is used in the program and the
namespace scope definition shall not contain an initializer.

Your testcase doesn't have the needed 
const int myclass::BUFF_SIZE;
anywhere.


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c++/45082] Static const signed int class member causes undefined symbol.
  2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
  2010-07-26 15:32 ` [Bug c++/45082] " jakub at gcc dot gnu dot org
@ 2010-07-26 15:59 ` rwitmer at xmission dot com
  2010-07-26 16:33 ` redi at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: rwitmer at xmission dot com @ 2010-07-26 15:59 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from rwitmer at xmission dot com  2010-07-26 15:59 -------
I agree with your assessment.  Adding const int myclass::BUFF_SIZE; resolves
the issue. 

The bug/feature may be that re-typing BUFF_SIZE to static const unsigned int
allows the compiler to not report a problem.  It doesn't require a const
unsigned myclass::BUFF_SIZE; anywhere and still compiles when it shouldn't.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c++/45082] Static const signed int class member causes undefined symbol.
  2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
  2010-07-26 15:32 ` [Bug c++/45082] " jakub at gcc dot gnu dot org
  2010-07-26 15:59 ` rwitmer at xmission dot com
@ 2010-07-26 16:33 ` redi at gcc dot gnu dot org
  2010-07-26 16:37 ` redi at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu dot org @ 2010-07-26 16:33 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from redi at gcc dot gnu dot org  2010-07-26 16:32 -------
(In reply to comment #2)
> The bug/feature may be that re-typing BUFF_SIZE to static const unsigned int
> allows the compiler to not report a problem.

You're not "re-typing" it, you're providing a definition for a variable that
was previously only declared, not defined.

>  It doesn't require a const
> unsigned myclass::BUFF_SIZE; anywhere 

Yes it does, it requires it where you bind a reference to the variable.

If you only want it to be used as an integral constant, don't use it in a
context that requires a variable (e.g. reference binding)

> and still compiles when it shouldn't.

There are dozens of (invalid) bug reports in bugzilla about this, feel free to
search for more details.
The compiler must not reject your program as it doesn't know until link time
that you've failed to define the symbol. It could be defined in some other
object or library that you link to later.

The bug was in your program, not the compiler.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c++/45082] Static const signed int class member causes undefined symbol.
  2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
                   ` (2 preceding siblings ...)
  2010-07-26 16:33 ` redi at gcc dot gnu dot org
@ 2010-07-26 16:37 ` redi at gcc dot gnu dot org
  2010-07-27 15:27 ` rwitmer at xmission dot com
  2010-07-27 23:55 ` redi at gcc dot gnu dot org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu dot org @ 2010-07-26 16:37 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from redi at gcc dot gnu dot org  2010-07-26 16:37 -------
(In reply to comment #3)
> 
> If you only want it to be used as an integral constant, don't use it in a
> context that requires a variable (e.g. reference binding)

e.g.
   funky((int)myclass::BUFF_SIZE);

This means the reference binds to a temporary, not to your class variable, and
therefore the compiler only needs the value of BUFF_SIZE, not it's definition.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c++/45082] Static const signed int class member causes undefined symbol.
  2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
                   ` (3 preceding siblings ...)
  2010-07-26 16:37 ` redi at gcc dot gnu dot org
@ 2010-07-27 15:27 ` rwitmer at xmission dot com
  2010-07-27 23:55 ` redi at gcc dot gnu dot org
  5 siblings, 0 replies; 7+ messages in thread
From: rwitmer at xmission dot com @ 2010-07-27 15:27 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from rwitmer at xmission dot com  2010-07-27 15:27 -------
Thanks for all the great comments and insight.

I'm still confused as to why when the BUFF_SIZE was defined as:
static const   signed int BUFF_SIZE = 20;
it caused the error, but when it was defined as:
static const unsigned int BUFF_SIZE = 20;
it did not.

void funky(const int& in) is an example of a library call I had to use, I have
no control over the author's over zealousness on using a const int& parameter.

There were 2 things that solved the problem I was seeing:

1. Adding a const   signed int BUFF_SIZE; line to the .cpp file.  

I've seen lots of code where we define constants ala, static const int
BUFF_SIZE=20; in the .hpp file without any const int myclass::BUFF_SIZE; in the
.cpp files.  Is that wrong to exclude them, should we be including them in the
.cpp file?

2. Declaring the type during the call, ala, funky((int)myclass::BUFF_SIZE);

I'm not sure which is the better solution.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c++/45082] Static const signed int class member causes undefined symbol.
  2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
                   ` (4 preceding siblings ...)
  2010-07-27 15:27 ` rwitmer at xmission dot com
@ 2010-07-27 23:55 ` redi at gcc dot gnu dot org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu dot org @ 2010-07-27 23:55 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from redi at gcc dot gnu dot org  2010-07-27 23:54 -------
(In reply to comment #5)
> Thanks for all the great comments and insight.
> 
> I'm still confused as to why when the BUFF_SIZE was defined as:
> static const   signed int BUFF_SIZE = 20;
> it caused the error, but when it was defined as:
> static const unsigned int BUFF_SIZE = 20;
> it did not.

Because you can't bind const int& to an unsigned int, so a temporary is created
and the reference bound to that.  When the variable has type int the reference
can bind to it directly.


> There were 2 things that solved the problem I was seeing:
> 
> 1. Adding a const   signed int BUFF_SIZE; line to the .cpp file.  
> 
> I've seen lots of code where we define constants ala, static const int
> BUFF_SIZE=20; in the .hpp file without any const int myclass::BUFF_SIZE; in the
> .cpp files.  Is that wrong to exclude them, should we be including them in the
> .cpp file?

Yes, if the variable is "used" in the program, see the reference from the
standard that Jakub posted days ago in comment 1

> 2. Declaring the type during the call, ala, funky((int)myclass::BUFF_SIZE);

You might have misunderstood that as well, there's no "declaring the type"
there, it's creating a temporary which the reference binds to.

> I'm not sure which is the better solution.

Again, please follow up somewhere else, GCC's bugzilla is not the right place
to learn the rules of C++.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45082


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-07-27 23:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-26 15:25 [Bug c++/45082] New: Static const signed int class member causes undefined symbol rwitmer at xmission dot com
2010-07-26 15:32 ` [Bug c++/45082] " jakub at gcc dot gnu dot org
2010-07-26 15:59 ` rwitmer at xmission dot com
2010-07-26 16:33 ` redi at gcc dot gnu dot org
2010-07-26 16:37 ` redi at gcc dot gnu dot org
2010-07-27 15:27 ` rwitmer at xmission dot com
2010-07-27 23:55 ` redi at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).