Template friend function injection

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Victor Bazarov

    #16
    Re: Template friend function injection

    Victor Bazarov wrote:
    H9XLrv5oXVNvHiU I@spambox.us wrote:
    >On Jul 11, 7:53 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
    >>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.c pp
    /tmp/ccCNJWBg.o: In function `main':
    test_template.c pp:(.text+0x12) : undefined reference to `Function()'
    collect2: ld returned 1 exit status
    Ubuntu-bazarov:~$ g++ -c test_template.c pp -o test_template.o
    Ubuntu-bazarov:~$ nm test_template.o
    U _Z8Functionv
    U __gxx_personali ty_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

    Comment

    • H9XLrv5oXVNvHiUI@spambox.us

      #17
      Re: Template friend function injection

      On Jul 11, 8:33 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
      Victor Bazarov wrote:
      H9XLrv5oXVNvH.. .@spambox.us wrote:
      On Jul 11, 7:53 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
      >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.c pp
           /tmp/ccCNJWBg.o: In function `main':
           test_template.c pp:(.text+0x12) : undefined reference to `Function()'
           collect2: ld returned 1 exit status
           Ubuntu-bazarov:~$ g++ -c test_template.c pp -o test_template.o
           Ubuntu-bazarov:~$ nm test_template.o
                    U _Z8Functionv
                    U __gxx_personali ty_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(noin line) but I don't know if GCC has some
      equivalent (I guess it does though).

      Comment

      • H9XLrv5oXVNvHiUI@spambox.us

        #18
        Re: Template friend function injection

        Also, I tried this on Open Watcom and it compiles and link it without
        any problem and the executable works of course.

        Comment

        • H9XLrv5oXVNvHiUI@spambox.us

          #19
          Re: Template friend function injection

          On Jul 11, 8:44 pm, H9XLrv5oXVNvH.. .@spambox.us wrote:
          On Jul 11, 8:33 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
          >
          >
          >
          Victor Bazarov wrote:
          H9XLrv5oXVNvH.. .@spambox.us wrote:
          >On Jul 11, 7:53 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
          >>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.c pp
               /tmp/ccCNJWBg.o: In function `main':
               test_template.c pp:(.text+0x12) : undefined reference to `Function()'
               collect2: ld returned 1 exit status
               Ubuntu-bazarov:~$ g++ -c test_template.c pp -o test_template.o
               Ubuntu-bazarov:~$ nm test_template.o
                        U _Z8Functionv
                        U __gxx_personali ty_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(noin line) 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.

          Comment

          • =?ISO-8859-1?Q?Marcel_M=FCller?=

            #20
            Re: Template friend function injection

            H9XLrv5oXVNvHiU I@spambox.us wrote:
            On Jul 11, 6:53 pm, Marcel Müller <news.5.ma...@s pamgourmet.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>(con st T&);
            };

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

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


            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

            Comment

            • H9XLrv5oXVNvHiUI@spambox.us

              #21
              Re: Template friend function injection

              On Jul 11, 9:27 pm, Marcel Müller <news.5.ma...@s pamgourmet.org>
              wrote:
              H9XLrv5oXVNvH.. .@spambox.us wrote:
              On Jul 11, 6:53 pm, Marcel Müller <news.5.ma...@s pamgourmet.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>(con st T&);
              >
              };
              >
              template <typename T>
              void Function(const T& arg)
              { printf("Functio n()"); getchar(); }
              >
              int main(int argc, char* argv[])
              {
                      Function(Test<i nt>());
              >
              }
              >
              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.

              Comment

              • H9XLrv5oXVNvHiUI@spambox.us

                #22
                Re: Template friend function injection

                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.

                Comment

                Working...