c++c++11gsoap

Problem with global namespace on g++ 4.8.5 (maybe incomplete C++11 support)


I have prepared a project on an up-to-date computer using -std=c++11. Now, I have to compile it on g++ 4.8.5 (Red Hat 4.8.5-39). To my surprise, support for C++11 standard on this system seems to be incomplete. Please note, that the project depends on gsoap library which is also older on the production system.

I am using the following construct:

class GeoGrid : public ::GeoGrid::GeoGridServiceSoapBindingProxy
{
public:
  ...
  using ContextType = ::GeoGrid::GeoGrid2__ContextType;
  ...
}

I get the following error on the old system:

api-2-0.h:434:23: error: expected type-specifier before ‘::’ token
   using ContextType = ::GeoGrid::GeoGrid2__ContextType;

I do not know if this is produced due to the old gsoap or just old g++.

My question is if this can be resolved without upgrading the system? I have to admit that I do not completelly understand all the consequences of using ‘::’ token at the beginning, it was simply a lucky guess that works perfectly on the new system.


Solution

  • Your snippet consistent with following situation:

    /*
    struct A {
        struct B {};
    }; */
    
    namespace X 
    {
    struct A {
        using B = ::A::B;    
    };
    }
    

    producing with new gcc (v10)

    error: 'A' in namespace '::' does not name a type
         using C = ::A::B;
    

    or this with old versions (v 4.7+)

     error: expected type-specifier before '::' token
         using C = ::A::B;
    

    The error above is generated only in the case when there is no A::B (GeoGrid::GeoGridServiceSoapBindingProxy in your case) in global namespace, thus ::A::B is not a legal typename, therefore compiler considers A being a legal typename from current context's scope and messages about lack of required identifier of context before the scope divider ::. The error message for newer versions is more readable than the technically correct but misleading older one.

    Another version of this situation would be

    struct A {
        using C = ::A::B;
        struct B {};
        
    };
    

    At the line where using C is present, B doesn't exist yet as a type, resulting in same error message for GCC 4.8. Newer versions would tell that type is incomplete.

     error: invalid use of incomplete type 'struct A'
         using C = ::A::B;
    

    In both cases it's an indication of malformed program, not of lack of standard support.