Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template friend function injection

Reply
Thread Tools

Template friend function injection

 
 
H9XLrv5oXVNvHiUI@spambox.us
Guest
Posts: n/a
 
      07-11-2008
On Jul 11, 8:33*pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Victor Bazarov wrote:
> > H9XLrv5oXVNvH...@spambox.us wrote:
> >> On Jul 11, 7:53 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> >>> H9XLrv5oXVNvH...@spambox.us wrote:
> >>>> [..]
> >>>> From what I know a function gets inlined only when declaration and
> >>>> definition occur in the same place, which is not true for my code.
> >>> Is that code different from what you posted?

>
> >> I don't understand the question. I'm talking about the code I posted,
> >> which doesn't compile as well as my real code I'm working on.

>
> > I wasn't sure whether you meant the code you posted or some other code
> > in which the template and its explicit instantiation were in a different
> > (than 'main') translation unit. *Can you try your code on a different
> > compiler? *I am going to try in GCC on Linux. *Will report with results
> > in a few minutes...

>
> Tried it with GCC 4.2.3 on Ubuntu. *Here's the output:
>
> * * *Ubuntu-bazarov:~$ g++ test_template.cpp
> * * */tmp/ccCNJWBg.o: In function `main':
> * * *test_template.cpp.text+0x12): undefined reference to `Function()'
> * * *collect2: ld returned 1 exit status
> * * *Ubuntu-bazarov:~$ g++ -c test_template.cpp -o test_template.o
> * * *Ubuntu-bazarov:~$ nm test_template.o
> * * * * * * * U _Z8Functionv
> * * * * * * * U __gxx_personality_v0
> * * *00000000 T main
> * * *Ubuntu-bazarov:~$
>
> As we can see, the function 'Function' does not get defined in the
> module although the template Test is instantiated. *That looks like an
> oversight on GCC part :*)
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


Ok, so the function gets probably inlined? Could you try to copy/paste
the printf() call many times so that the compiler doesn't inline it?
Or is there somethin for not making GCC inline a function? I know on
MSVC there's the __declspec(noinline) but I don't know if GCC has some
equivalent (I guess it does though).
 
Reply With Quote
 
 
 
 
H9XLrv5oXVNvHiUI@spambox.us
Guest
Posts: n/a
 
      07-11-2008
Also, I tried this on Open Watcom and it compiles and link it without
any problem and the executable works of course.
 
Reply With Quote
 
 
 
 
H9XLrv5oXVNvHiUI@spambox.us
Guest
Posts: n/a
 
      07-11-2008
On Jul 11, 8:44*pm, H9XLrv5oXVNvH...@spambox.us wrote:
> On Jul 11, 8:33*pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>
>
>
> > Victor Bazarov wrote:
> > > H9XLrv5oXVNvH...@spambox.us wrote:
> > >> On Jul 11, 7:53 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> > >>> H9XLrv5oXVNvH...@spambox.us wrote:
> > >>>> [..]
> > >>>> From what I know a function gets inlined only when declaration and
> > >>>> definition occur in the same place, which is not true for my code.
> > >>> Is that code different from what you posted?

>
> > >> I don't understand the question. I'm talking about the code I posted,
> > >> which doesn't compile as well as my real code I'm working on.

>
> > > I wasn't sure whether you meant the code you posted or some other code
> > > in which the template and its explicit instantiation were in a different
> > > (than 'main') translation unit. *Can you try your code on a different
> > > compiler? *I am going to try in GCC on Linux. *Will report with results
> > > in a few minutes...

>
> > Tried it with GCC 4.2.3 on Ubuntu. *Here's the output:

>
> > * * *Ubuntu-bazarov:~$ g++ test_template.cpp
> > * * */tmp/ccCNJWBg.o: In function `main':
> > * * *test_template.cpp.text+0x12): undefined reference to `Function()'
> > * * *collect2: ld returned 1 exit status
> > * * *Ubuntu-bazarov:~$ g++ -c test_template.cpp -o test_template.o
> > * * *Ubuntu-bazarov:~$ nm test_template.o
> > * * * * * * * U _Z8Functionv
> > * * * * * * * U __gxx_personality_v0
> > * * *00000000 T main
> > * * *Ubuntu-bazarov:~$

>
> > As we can see, the function 'Function' does not get defined in the
> > module although the template Test is instantiated. *That looks like an
> > oversight on GCC part :*)

>
> > V
> > --
> > Please remove capital 'A's when replying by e-mail
> > I do not respond to top-posted replies, please don't ask

>
> Ok, so the function gets probably inlined? Could you try to copy/paste
> the printf() call many times so that the compiler doesn't inline it?
> Or is there somethin for not making GCC inline a function? I know on
> MSVC there's the __declspec(noinline) but I don't know if GCC has some
> equivalent (I guess it does though).


Nop, even with the attribute __attribute__ ((noinline)) it still gives
that error about Function() not being defined.
 
Reply With Quote
 
Marcel Müller
Guest
Posts: n/a
 
      07-11-2008
wrote:
> On Jul 11, 6:53 pm, Marcel Müller <news.5.ma...@spamgourmet.org>
> wrote:
>
>> I expected something like that. That still gives you the chance, to use
>> the functions defined inside Test not before the definition of test.
>>
>> Furthermore you can define a template version of Function outside Test
>> for this purpose.
>>
>> Marcel

>
> Can you explain this point better? Especially the last sentence. If I
> define a template version of Function() then I would not be able to
> call it from main, am I wrong? Can you provide an example? Thank you.


template <typename T>
void Function(const T& arg);

template <typename T>
class Test
{
public:
friend void Function<T>(const T&);
};

template <typename T>
void Function(const T& arg)
{ printf("Function()"); getchar(); }

int main(int argc, char* argv[])
{
Function(Test<int>());
}


But from your question I guess that you want to do something entirely
different. You want to control by the statement
template class Test<int>;
which version of Function is implemented, isn't it? The argument list of
Function does not depend on T at all, but the body does. This is evil.
Think what is happening if you write
template class Test<int>;
template class Test<char>;

You will get an error in this case, but only if both of them are defined
in the same module. Otherwise you violate the ODR and get undefined
behavior.

In this case a simple
typedef int myFunctionType;
would do a better job.


Marcel
 
Reply With Quote
 
H9XLrv5oXVNvHiUI@spambox.us
Guest
Posts: n/a
 
      07-11-2008
On Jul 11, 9:27*pm, Marcel Müller <news.5.ma...@spamgourmet.org>
wrote:
> H9XLrv5oXVNvH...@spambox.us wrote:
> > On Jul 11, 6:53 pm, Marcel Müller <news.5.ma...@spamgourmet.org>
> > wrote:

>
> >> I expected something like that. That still gives you the chance, to use
> >> the functions defined inside Test not before the definition of test.

>
> >> Furthermore you can define a template version of Function outside Test
> >> for this purpose.

>
> >> Marcel

>
> > Can you explain this point better? Especially the last sentence. If I
> > define a template version of Function() then I would not be able to
> > call it from main, am I wrong? Can you provide an example? Thank you.

>
> template <typename T>
> void Function(const T& arg);
>
> template <typename T>
> class Test
> {
> public:
> * * * * friend void Function<T>(const T&);
>
> };
>
> template <typename T>
> void Function(const T& arg)
> { printf("Function()"); getchar(); }
>
> int main(int argc, char* argv[])
> {
> * * * * Function(Test<int>());
>
> }
>
> But from your question I guess that you want to do something entirely
> different. You want to control by the statement
> * *template class Test<int>;
> which version of Function is implemented, isn't it? The argument list of
> Function does not depend on T at all, but the body does. This is evil.
> Think what is happening if you write
> * *template class Test<int>;
> * *template class Test<char>;
>
> You will get an error in this case, but only if both of them are defined
> in the same module. Otherwise you violate the ODR and get undefined
> behavior.
>
> In this case a simple
> * *typedef int myFunctionType;
> would do a better job.
>
> Marcel


Yes I know most of the times this would be seen as a bad design choice
but in this case is instead a perfect solution to a problem because I
know as a design principle that the Test class template will never be
instantiated more than one time so there won't be any duplicate
definition of Function(). Also if you follow the conversation with
Victor Bazarov he informed me that my code is completely standard-
compliant thus making this a possible GCC bug. I've also double-
checked that this code compiles and links fine on the Open Watcom
compiler.
 
Reply With Quote
 
H9XLrv5oXVNvHiUI@spambox.us
Guest
Posts: n/a
 
      07-11-2008
On Jul 11, 8:51*pm, H9XLrv5oXVNvH...@spambox.us wrote:
> Also, I tried this on Open Watcom and it compiles and link it without
> any problem and the executable works of course.


Furthermore I was wrong about having a way to compile this code in
visualc++. In fact that code was slightly different and visualc++
seems not only unable to compile any kind of code like this, but it
also crashes when you try to make it to.
So basically so far the only compiler able to compile this kind of
code seems to be this Open Watcom.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
friend injection: Clarification Required moogyd C++ 5 10-26-2010 09:06 AM
Declaring a template class with two template params a friend in anon-template class A L C++ 1 08-25-2010 07:25 AM
Problem with defining template friend function of a template class. PengYu.UT@gmail.com C++ 2 11-09-2005 08:27 PM
about "friend name injection" zealotcat@gmail.com C++ 0 01-21-2005 03:31 AM
using friend function template in class template Yueh-Wei Hu C++ 0 05-23-2004 11:36 AM



Advertisments