Re: Isn't this a conversion bug in gcc?
 
On 30 Jul., 02:22, Nikolay Ivchenkov <ts...@mail.ru> wrote:
On 29 Jul, 17:48, Daniel Kr?gler <daniel.krueg...@googlemail.com>
wrote:
ad c) I agree that the Standard in general includes the instantiation
of definitions *when* they are required to exist and *when* they
are available.
    #include <iostream>
    int n = 0;
    template <class T>
        struct B
    {
        B()
        {
            if (n)
                f();
                // pure function call
                // (see the suggested resolution for core issue 230)
        }
        virtual void f() = 0;
    };
    template <class T>
        void B<T>::f()
            { std::cout << "B<T>::f()\n"; }
    struct D : B<int>
    {
        D()
            { static_cast<B<int> &>(*this).f(); }
        void f()
            { std::cout << "D::f()\n"; }
    };
    int main()
    {
        std::cin >> n;
        D();
    }
A definition of B<int>::f is not required to be exist. Thus, we can't
apply 14.7.1/2
"Unless a function template specialization has been explicitly
instantiated or explicitly specialized, the function template
specialization is implicitly instantiated when the specialization is
referenced in a context that requires a function definition to exist."
Must the definition of B<int>::f be instantiated?
Yes.
Even though B<int>::f is not required to exist in any general program
it is required to exist in this particular program, because it is
still used
in the sense of the *general* requirements specified in 3.2/2:
"An expression is potentially evaluated unless it is an unevaluated
operand (Clause 5) or a subexpression thereof. A variable or non-
overloaded function whose name appears as a potentially-evaluated
expression is used unless it is an object that satisfies the
requirements for appearing in a constant expression (5.19)
and the lvalue-to-rvalue conversion (4.1) is immediately applied.[..]"
The example invokes the constructor of B as part of a potentially
evaluated expression. Note that the refining sentence:
"A virtual member function is used if it is not pure."
does not declare a pure virtual function as *unused*, it only declares
*any* non-pure virtual function as *used*. This is a big difference,
because it does not make the former requirements invalid.
HTH & Greetings from Bremen,
Daniel Kr?gler
-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]