Bug 42330 - undefined reference to "static const int" in class when passing as "const int &" to a function
Summary: undefined reference to "static const int" in class when passing as "const int...
Status: RESOLVED DUPLICATE of bug 42101
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-12-08 04:30 UTC by Aijun Bai
Modified: 2009-12-08 14:15 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aijun Bai 2009-12-08 04:30:57 UTC
consider the flowing code:

struct A {
    static const int i = 0;
};

void foo(int)
{
}

void bar(const int &)
{
}

int main() {
    foo(A::i);
    bar(A::i);

    return 0;
}

when compiling with -O0 option, g++ reports that: undefined reference to `A::i',
but it will be ok if i use -O3 option.

gcc -v says:
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8)
Comment 1 Paolo Carlini 2009-12-08 09:18:30 UTC
You aren't defining anywhere A::i, just add, after struct A:

  const int A::i;

and things will be fine.

*** This bug has been marked as a duplicate of 42101 ***
Comment 2 Aijun Bai 2009-12-08 09:46:52 UTC
(In reply to comment #1)
> You aren't defining anywhere A::i, just add, after struct A:
> 
>   const int A::i;
> 
> and things will be fine.
> 
> *** This bug has been marked as a duplicate of 42101 ***
> 

thanks for your reply.

i found that no errors will be reported if i delete the line `bar(A::i)', so is that a bug?

in fact the original code is like:
template <int>
class A
{
    static const int i = -1;
}

template <>
class A<0>
{
    static const int i = 0;
}

//and some other specializations...

and i don't want to write lots of "const int A<N>::i"...
Comment 3 Jonathan Wakely 2009-12-08 09:48:54 UTC
(In reply to comment #2)
> and i don't want to write lots of "const int A<N>::i"...

You have to, your code is not valid if you use A::i in the program but it has no definition.  This is not a compiler bug.




*** This bug has been marked as a duplicate of 42101 ***
Comment 4 Jonathan Wakely 2009-12-08 09:50:45 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > and i don't want to write lots of "const int A<N>::i"...
> 
> You have to, your code is not valid if you use A::i in the program but it has
> no definition.  This is not a compiler bug.

Actually you don't have to write lots, just one:

template<int N> const A<N>::i;

Comment 5 Aijun Bai 2009-12-08 11:52:39 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > (In reply to comment #2)
> > > and i don't want to write lots of "const int A<N>::i"...
> > 
> > You have to, your code is not valid if you use A::i in the program but it has
> > no definition.  This is not a compiler bug.
> 
> Actually you don't have to write lots, just one:
> 
> template<int N> const A<N>::i;
> 

I tried so, but it seems do not work, could you please explain more detailedly? thx~
Comment 6 Jonathan Wakely 2009-12-08 12:23:28 UTC
(In reply to comment #5)
> > 
> > template<int N> const A<N>::i;
> > 
> 
> I tried so, but it seems do not work, could you please explain more detailedly?
> thx~

I missed the "int" out:

template<int N> const int A<N>::i;




Comment 7 Aijun Bai 2009-12-08 13:02:21 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > > 
> > > template<int N> const A<N>::i;
> > > 
> > 
> > I tried so, but it seems do not work, could you please explain more detailedly?
> > thx~
> 
> I missed the "int" out:
> 
> template<int N> const int A<N>::i;
> 

thanks for your help, but it still can not be compiled under gcc 4.4.1
Comment 8 Paolo Carlini 2009-12-08 13:12:49 UTC
Then show here exactly what you are trying to compile. Note: this is *not* gcc-help.
Comment 9 Aijun Bai 2009-12-08 14:06:25 UTC
(In reply to comment #8)
> Then show here exactly what you are trying to compile. Note: this is *not*
> gcc-help.
> 

alright, take the flowing code as an example:

template<int>
struct A {
    static const int i = -1;
};

template<>
struct A<0> {
    static const int i = 0;
};

template<>
struct A<1> {
    static const int i = 1;
};

template <int N> const int A<N>::i;

int foo(int)
{
}

int bar(const int &)
{
}

int main()
{
    foo(A<1>::i); //ok here
    bar(A<0>::i); //g++ complains undefined reference to `A<0>::i'

    return 0;
}
Comment 10 Paolo Carlini 2009-12-08 14:15:42 UTC
Since you have specializations for A, you also need, in general, the corresponding definitions:

const int A<0>::i;
const int A<1>::i;