Boost logo

Boost :

Subject: Re: [boost] [typeof] GCC error: expression not defined in this scope
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-02-27 12:01:37


On Fri, Feb 25, 2011 at 3:06 PM, Vicente Botet <vicente.botet_at_[hidden]> wrote:
>
>
> Lorenzo Caminiti wrote:
>>
>> On Mon, Feb 7, 2011 at 5:29 PM, Steven Watanabe <watanabesj_at_[hidden]>
>> wrote:
>>
>>
>> Hello all,
>>
>> Why the following TYPEOF code does not compile on GCC but it does on
>> MSVC? Is this a GCC bug? If so, is there a workaround for it?
>>
>> #include <boost/typeof/typeof.hpp>
>>
>> int f() { return -1; }
>>
>> template<typename T>
>> void g(T x) {
>>     int (deduce_func)();
>>     typedef BOOST_TYPEOF_TPL(deduce_func) func_type; // error also if
>> TYPEOF is used instead of TYPEOF_TPL
>>
>>     struct s {
>>         void call(func_type func) { func(); } // line 12
>>     } ss;
>>     ss.call(f); // line 14
>> }
>>
>> int main() {
>>     g(1); // line 18
>>     return 0;
>> }
>>
>> $ g++ -Wall -Werror -I../../.. r03.cpp
>> r03.cpp: In member function ‘void g(T)::s::call(__typeof__
>> (boost::type_of::ensure_obj(deduce_func))) [with T = int]’:
>> r03.cpp:14:   instantiated from ‘void g(T) [with T = int]’
>> r03.cpp:18:   instantiated from here
>> r03.cpp:12: error: ‘deduce_func’ was not declared in this scope
>>
>> What is this error? I don't understand it because with the local
>> struct at line 12 I am just accessing the type generated by the
>> typedef and not the actual expression that was used to deduce such a
>> type...
>>
>>
>
> If I understand deduce_func should be a pointer to a function returning int.
> The declaration
>    int (deduce_func)();
>
> seems suspect to me. Have you tried with
>    int (*deduce_func)();

Yes, using the *deduce_func fixed the issue. However, while this small
example compiled by using *deduce_func, using *deduce_func caused an
internal GCC internal in my lager Boost.Local code where I using this
type deduction. I got around the GCC internal error doing the tagging
and wrapping that Boost.ScopeExit does. Essentially, I ended up using
code like this where boost_se_... are symbols defined by the scope
exit macro expansion:

#include <boost/type_traits.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/scope_exit.hpp>
#include <iostream>

int f() { return -1; }

template<typename T>
void g(T x) {
    T (*deduce_func)();
    typedef BOOST_TYPEOF_TPL(*deduce_func) func_type;

    BOOST_SCOPE_EXIT_TPL( (deduce_func) ) {
        std::cout << "exiting" << std::endl;
    } BOOST_SCOPE_EXIT_END

    typedef typename boost::remove_pointer<typename
boost_se_params_t_14::boost_se_param_t_0_14>::type ftype;
    typedef typename boost::function_traits<ftype>::result_type rtype;

    struct s {
        rtype call(typename
boost_se_params_t_14::boost_se_param_t_0_14 func) { func(); return -1;
}
    } ss;
    ss.call(&f);
}

int main() {
    g(1);
    return 0;
}

My Boost.Local code using code similar to the above now works on both
GCC and MSVC (without any internal compiler error).

Thanks.

-- 
Lorenzo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk