Compilation sequence - a feature or bug

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?iso-8859-2?q?Seweryn_Habdank-Wojew=F3dzki?=

    Compilation sequence - a feature or bug

    Hi

    There is an example of the code below (mostly written by P. Bindels).
    In that example is strongly highlighted that very important is the
    sequence
    of compiled code. In C++ could be assume that such a sequence exists.
    But the question is if it is a feature or it is a bug?
    Especially in the scope of that example we could observe that
    templates
    can be somehow separated from its specializations .

    Best regards.

    #include <iostream>

    template <class A>
    class T {
    A a;
    };

    class is_original_ver sion_of_templat e
    {
    public:
    static bool const value;
    };

    bool const is_original_ver sion_of_templat e::value
    (sizeof(T<void *>) == sizeof(T<void *>));

    template <class A>
    class T<A *{
    A *a[10];
    };

    class is_not_original _version_of_tem plate // specialized
    {
    public:
    static bool const value;
    };

    bool const is_not_original _version_of_tem plate::value
    (sizeof(T<void *>) == is_original_ver sion_of_templat e::value);

    int main()
    {
    std::cout << "is_original_ve rsion_of_templa te "
    << is_original_ver sion_of_templat e::value << '\n';

    std::cout << "is_not_origina l_version_of_te mplate "
    << is_not_original _version_of_tem plate::value << '\n';
    }

  • Zeppe

    #2
    Re: Compilation sequence - a feature or bug

    Seweryn Habdank-Wojewódzki wrote:
    Hi
    >
    There is an example of the code below (mostly written by P. Bindels).
    In that example is strongly highlighted that very important is the
    sequence
    of compiled code. In C++ could be assume that such a sequence exists.
    But the question is if it is a feature or it is a bug?
    Especially in the scope of that example we could observe that
    templates
    can be somehow separated from its specializations .
    There are definite rules for the template argument resolution. Well,
    actually it's a little it complex stuff, but the common-sense rule
    applies the most of the times. That is, in this situation, if you want
    to use a specialisation, the definition of the specialisation has to be
    visible in every place in which you instantiate the templates that
    whould be specialised.
    #include <iostream>
    >
    template <class A>
    class T {
    A a;
    };
    >
    class is_original_ver sion_of_templat e
    {
    public:
    static bool const value;
    };
    I can't understand the meaning of this code...
    bool const is_original_ver sion_of_templat e::value
    (sizeof(T<void *>) == sizeof(T<void *>));
    This is always true...
    template <class A>
    class T<A *{
    A *a[10];
    };
    Ah, that's bad. The standard (14.3.3#2) says:
    Any partial specializations (14.5.4) associated with the primary class
    template are considered when a specialization based on the template
    template parameter is instantiated. If a specialization is not visible
    at the point of instantiation, and it would have been selected had it
    been visible, the program is ill-formed; no diagnostic is required.
    This applies in your case.
    class is_not_original _version_of_tem plate // specialized
    {
    public:
    static bool const value;
    };
    >
    bool const is_not_original _version_of_tem plate::value
    (sizeof(T<void *>) == is_original_ver sion_of_templat e::value);
    Here you are comparing a size_type with a bool (that is always true).
    It makes no sense.

    Regards,

    Zeppe

    Comment

    • =?iso-8859-1?q?Seweryn_Habdank-Wojew=F3dzki?=

      #3
      Re: Compilation sequence - a feature or bug

      Hi!

      Thanks for the reply.
      Ah, that's bad. The standard (14.3.3#2) says:
      Any partial specializations (14.5.4) associated with the primary class
      template are considered when a specialization based on the template
      template parameter is instantiated. If a specialization is not visible
      at the point of instantiation, and it would have been selected had it
      been visible, the program is ill-formed; no diagnostic is required.
      This applies in your case.
      Yes I understand. But I am looking if something is useful in that
      case. I have another example of such a code. When I am blocking one
      particular specialisation by using explicit instantiation before more
      general specialisation. In the code calling "T<int*, double*>::value ;"
      will cause compilation error.

      Regards.
      #include <iostream>
      #include <boost/static_assert.h pp>

      template <class A, class B>
      class T {};

      template class T<int*, double*>;

      template <class A, class B>
      struct T<A *, B{
      A a[10];
      B * b[7];
      enum { value = sizeof(A*[10]) + sizeof(B*[7]) };
      };

      template <typename A, typename B>
      struct Func { enum { value = (sizeof(T<A,B>) == 1) }; };

      int main()
      {
      using std::cout;
      //T<int*, double*>::value ;
      int const b = T<int*,double>: :value;
      int const a = T<double*,int>: :value;
      int const c = Func<int*,doubl e*>::value;
      BOOST_STATIC_AS SERT (c == 1);
      int const d = Func<int*,doubl e>::value;
      BOOST_STATIC_AS SERT (d != 1);
      cout << b << ' ' << a << ' ' << c << ' ' << d << '\n';
      return a;
      }



      Comment

      • Zeppe

        #4
        Re: Compilation sequence - a feature or bug

        Seweryn Habdank-Wojewódzki wrote:
        Hi!
        >
        Thanks for the reply.
        >
        >Ah, that's bad. The standard (14.3.3#2) says:
        >Any partial specializations (14.5.4) associated with the primary class
        >template are considered when a specialization based on the template
        >template parameter is instantiated. If a specialization is not visible
        >at the point of instantiation, and it would have been selected had it
        >been visible, the program is ill-formed; no diagnostic is required.
        >This applies in your case.
        >
        Yes I understand. But I am looking if something is useful in that
        case.
        Sorry, I;ve quoted the wrong piece of standard. The correct one is in
        14.5.4#1:
        If a template is partially specialized then that partial specialization
        shall be declared before the first use of that partial specialization
        that would cause an implicit instantiation to take place, in every
        translation unit in which such a use occurs; no diagnostic is required.

        It's quite different, and it seems to allow your example. But 14.6.4.1#7
        tells:
        A specialization for any template may have points of instantiation in
        multiple translation units. If two different points of instantiation
        give a template specialization different meanings according to the one
        definition rule (3.2), the program is ill-formed, no diagnostic required.

        In my opinion, this means that as long as you make sure that the
        particular specialisation is explicitly instantiated *before* the
        definition of the general specialization in all the translation units in
        which it is used, it should be fine.
        I have another example of such a code. When I am blocking one
        particular specialisation by using explicit instantiation before more
        general specialisation. In the code calling "T<int*, double*>::value ;"
        will cause compilation error.
        I think it's fine, according to the standard paragraphs that I cited.

        Regards,

        Zeppe

        Comment

        • =?iso-8859-1?q?Seweryn_Habdank-Wojew=F3dzki?=

          #5
          Re: Compilation sequence - a feature or bug

          Hi

          On 26 Cze, 01:29, Zeppe <z...@remove.al l.this.long.com ment.email.it>
          wrote:
          Sorry, I;ve quoted the wrong piece of standard. The correct one is in
          14.5.4#1:
          If a template is partially specialized then that partial specialization
          shall be declared before the first use
          The question is if e.g. instantiation is a use of template or not.

          so the case when you will have:

          template <typename T>
          class A {};

          template class A<void*>; // this is use or not.

          template <typename T>
          class A<T*{};
          of that partial specialization
          that would cause an implicit instantiation to take place, in every
          translation unit in which such a use occurs; no diagnostic is required.
          Regards.


          Comment

          • Zeppe

            #6
            Re: Compilation sequence - a feature or bug

            Seweryn Habdank-Wojewódzki wrote:
            Hi
            >
            On 26 Cze, 01:29, Zeppe <z...@remove.al l.this.long.com ment.email.it>
            wrote:
            >Sorry, I;ve quoted the wrong piece of standard. The correct one is in
            >14.5.4#1:
            >If a template is partially specialized then that partial specialization
            >shall be declared before the first use
            >
            The question is if e.g. instantiation is a use of template or not.
            What do you mean as "use of template"?
            >
            so the case when you will have:
            >
            template <typename T>
            class A {};
            >
            template class A<void*>; // this is use or not.
            >
            This one is an explicit template instantiation. It forces the template
            class A to be inst\0ntiated with the paramater T = void*.

            Regards,

            Zeppe

            Comment

            • Victor Bazarov

              #7
              Re: Compilation sequence - a feature or bug

              Zeppe wrote:
              Seweryn Habdank-Wojewódzki wrote:
              >Hi
              >>
              >On 26 Cze, 01:29, Zeppe <z...@remove.al l.this.long.com ment.email.it>
              >wrote:
              >>Sorry, I;ve quoted the wrong piece of standard. The correct one is
              >>in 14.5.4#1:
              >>If a template is partially specialized then that partial
              >>specializatio n shall be declared before the first use
              >>
              >The question is if e.g. instantiation is a use of template or not.
              >
              What do you mean as "use of template"?
              My guess is the OP means whatever the Standard means. The question
              is, essentially, what the heck is the "use" in 14.5.4?
              >so the case when you will have:
              >>
              >template <typename T>
              >class A {};
              >>
              >template class A<void*>; // this is use or not.
              >>
              >
              This one is an explicit template instantiation. It forces the template
              class A to be instantiated with the paramater T = void*.
              >
              But is it a "use", in terms of the Standard?

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


              Comment

              • Zeppe

                #8
                Re: Compilation sequence - a feature or bug

                Victor Bazarov wrote:
                Zeppe wrote:
                >Seweryn Habdank-Wojewódzki wrote:
                >>Hi
                >>>
                >>On 26 Cze, 01:29, Zeppe <z...@remove.al l.this.long.com ment.email.it>
                >>wrote:
                >>>Sorry, I;ve quoted the wrong piece of standard. The correct one is
                >>>in 14.5.4#1:
                >>>If a template is partially specialized then that partial
                >>>specializati on shall be declared before the first use
                >>The question is if e.g. instantiation is a use of template or not.
                >What do you mean as "use of template"?
                >
                My guess is the OP means whatever the Standard means. The question
                is, essentially, what the heck is the "use" in 14.5.4?
                >
                >>so the case when you will have:
                >>>
                >>template <typename T>
                >>class A {};
                >>>
                >>template class A<void*>; // this is use or not.
                >>>
                >This one is an explicit template instantiation. It forces the template
                >class A to be instantiated with the paramater T = void*.
                >>
                >
                But is it a "use", in terms of the Standard?
                >
                Well, I guess yes. I think that according to the standard, you can "use"
                different versions (specialization s) of the template. So, each time a
                template must be matched, a version (the most of the time, the most
                matching according to the template matching rules) will be "used".

                Having said so, the standard tells in 14.5.4 that if a template is
                partially specialised (that is, a partial specialisation exists in the
                program) then this partial specialisation has to be declared before the
                first "use" of the specialisation that would cause an implicit
                instantiation to take place. Which mean that *if* there is an
                instruction that "use" the specialisation (that means, that imply that
                version of the template to be considered for that piece of code) *and*
                this instruction _imply_ the implicit instantiation of the
                specialisation (that is, a more specialised version of the general
                template has not yet been explicitly, or even implicitly maybe (I have
                to check), instantiated), *then* the specialisation has to come before
                that instruction (obviously). And, additionally, this has to happen
                consistently in the whole program.

                This is IMHO.

                Regards,

                Zeppe

                Comment

                Working...