[Bug c++/56760] New: namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



 Bug #: 56760

   Summary: namespaces, templates and forwarding declarations.

Classification: Unclassified

   Product: gcc

   Version: 4.7.2

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: erik.thi...@thiele-hydraulik.de





Created attachment 29739

  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29739

v1 source code


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #1 from erik.thi...@thiele-hydraulik.de 2013-03-28 07:01:12 UTC ---

Created attachment 29740

  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29740

v2 source code


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #2 from erik.thi...@thiele-hydraulik.de 2013-03-28 07:05:22 UTC ---

You see attached two files. v1.cpp and v2.cpp



g++ --version

g++ (Debian 4.7.2-5) 4.7.2

Copyright (C) 2012 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



g++ -Wall v1.cpp

/tmp/ccZAyNEb.o: In function `void func

>(seco::contain > const&, nam::binbuffer&)':

v1.cpp:(.text._Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE[_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE]+0x16):

undefined reference to `void func >(seco::holder const&,

nam::binbuffer&)'

collect2: error: ld returned 1 exit status



g++ -Wall v2.cpp

--> no errors



in v1.cpp you see a commented out line with a template forward declaration. if

you comment that in:



g++ -Wall v1.cpp

--> no errors



The only difference between v1 and v2 is that in v2 you do not have the "nam"

namespace.


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #4 from erik.thi...@thiele-hydraulik.de 2013-03-28 07:58:00 UTC ---

The example is reduced very much. Actually I have a module for "holder" and one

for "contain" (separate compilation units). They do not know about each other.

I have this global mechanism called "func" which everybody can make

specializations for to enable his class to take part in this "func" stuff. What

func does is serialize a class into the "binbuffer" binary buffer. If you

create a custom class, you can let it take part in the "func" system and thus

make it serializable.



Everything works fine until I have a holder > or a

contain >. The problem is that I cannot have a forward declaration

because "contain" and "holder" don't know each other. This is like adding

forward declarations in system libraries like "vector<>" for user classes which

the STL developers of course cannot know.



v2.cpp does not have the "nam" namespace that "v1.cpp" has. But the "nam"

namespace is only for the "binbuffer" class. See that it has nothing to do with

the "seco" namespace or the global namespace that "func" is inside. For that

reason I do not understand why leaving out the "nam" namespace fixes the

problem.



I cannot find a workaround. The problem is that template implementations are

inside headers. So either "holder" or "contain" is defined and implemented

first. I cannot define "holder" and "contain" and then afterwards implement

"holder" and "contain". This would fix my problem but then the template

implementation cannot be inside the header anymore, at least I do not know how.

I would need a precompiler that splits header interfaces from header

implementations and first puts all interfaces and then all implementations.



Is there another workaround?



Sorry I do not understand your comment. Probably I miss some important point

somehow. Anyway I do not find a solution...


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #5 from erik.thi...@thiele-hydraulik.de 2013-03-28 08:22:19 UTC ---

Created attachment 29741

  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29741

v3 source code


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #6 from erik.thi...@thiele-hydraulik.de 2013-03-28 08:27:34 UTC ---

let me paste "v3 source code" that is also added as attachment:





namespace nam { class binbuffer {}; }



template void func (const T &a, nam::binbuffer &b);



namespace seco {

  template struct holder { X *fun; };

  template struct contain { T *wombat; };

}



template void func(const seco::contain &a, nam::binbuffer &b)

{ func(*a.wombat, b); }



template void func(const seco::holder &a, nam::binbuffer &b)

{ func(*a.fun, b); }



template<> void func(const int &a, nam::binbuffer &b) {}



int main()

{

  nam::binbuffer b;

  seco::holder foo;

  func(foo, b);

  seco::contain > containHolder;

  func(containHolder, b); // COMMENT THIS OUT AND IT WORKS

  return 0;

}





END OF CODE





when you compile this, it sais



g++ -Wall v3.cpp

/tmp/ccDElJvq.o: In function `void func

>(seco::contain > const&, nam::binbuffer&)':

v3.cpp:(.text._Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE[_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE]+0x16):

undefined reference to `void func >(seco::holder const&,

nam::binbuffer&)'

collect2: error: ld returned 1 exit status





but when you comment out the line "COMMENT THIS OUT AND IT WORKS" then it

compiles.



now consider the line "func(foo, b)". here exactly the function gets called

that the linker sais is not defined. How can the linker say the function is not

defined, even though it obviously is defined?



you can make it even more clear: comment out this:



//template void func(const seco::holder &a, nam::binbuffer &b)

//{ func(*a.fun, b); }



but reenable the line "COMMENT THIS OUT AND IT WORKS"



then you get this output:



g++ -Wall v3.cpp

/tmp/cc3keqh3.o: In function `main':

v3.cpp:(.text+0x1e): undefined reference to `void func

>(seco::holder const&, nam::binbuffer&)'

/tmp/cc3keqh3.o: In function `void func

>(seco::contain > const&, nam::binbuffer&)':

v3.cpp:(.text._Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE[_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE]+0x16):

undefined reference to `void func >(seco::holder const&,

nam::binbuffer&)'

collect2: error: ld returned 1 exit status



you see, it sais two times that the function is not defined. that's OK! now if

you reenable:



template void func(const seco::holder &a, nam::binbuffer &b)

{ func(*a.fun, b); }



then only the second error message keeps being there. but it misses exactly the

same function!



what's going on here? the function is there and it gets called once. why cannot

it get called twice???


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #8 from erik.thi...@thiele-hydraulik.de 2013-03-28 09:55:49 UTC ---

I read the section on name lookup changes at

http://gcc.gnu.org/gcc-4.7/porting_to.html



but it talks about a different kind of problem. Consider that there the

compiler does error messages. But here at our problem the linker (!) does the

error.



also the mentioned -fpermissive flag does not change the situation.


[Bug c++/56760] namespaces, templates and forwarding declarations.

2013-03-28 Thread erik.thi...@thiele-hydraulik.de


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



--- Comment #10 from erik.thi...@thiele-hydraulik.de 2013-03-28 16:50:06 UTC ---

But the function actually IS defined, because the call func(foo,b) works. Yes

it is not defined early enough maybe. But the linker is run after the compiler.

How can the linker differentiate about when something is implemented? doesn't

it just look for the symbol and if it is there, then it is there?



as mentioned in my post 2013-03-28 08:27:34 UTC the signature of the missing

implementation is exactly the same in the error message if you leave out the

template definition than if you do the line that you call invalid C++.



So maybe the linker output should show more detail. The linker sais that an

implementation is missing, which is NOT missing. so maybe there is some

additional clue that the linker could display here? is there some hidden

additional information in the function signature somehow?





the section about name lookup changes talks about the -fpermissive option which

should reactivate the old behaviour. but that does not work.





anyway... what could be a workaround? as mentioned earlier I cannot do a

forward declaration.



This really puzzles me...