tags:

views:

140

answers:

4

I have a template class with a static function (see Connect function below). This template class is part of a 3rd Party lib (call it LibA). My code uses this lib and includes the header below since I need to use the template class. When I compile my lib without inline functions (-fno-default-inline with gcc) I get no problems. When I compile in release (-O2), my application crashes.

I was wondering what the implications are of having a static function in a template and how inlining may affect this.

template<class T>
class TCPConnector
: public IOHandler {
private:
    string _ip;
    uint16_t _port;
    vector<uint32_t> _protocolChain;
    bool _closeSocket;
    Variant _customParameters;
public:

TCPConnector(int32_t fd, string ip, uint16_t port,
        vector<uint32_t>& protocolChain, const Variant& customParameters)
: IOHandler(fd, IOHT_TCP_CONNECTOR) {
    _ip = ip;
    _port = port;
    _protocolChain = protocolChain;
    _closeSocket = true;
    _customParameters = customParameters;
}

virtual ~TCPConnector() {
    //FINEST("Close socket: %d", _closeSocket);
    if (_closeSocket) {
        close(_fd);
        //FINEST("Socket closed!");
    }
}


static bool Connect(string ip, uint16_t port,
        vector<uint32_t>& protocolChain, Variant& customParameters) {

    protoent *pProtocol = getprotobyname("IP");
    if (pProtocol == NULL) {
        FATAL("Unable to resolve protocol number for IP");
        return 0;
    }

    int32_t fd = (int32_t) socket(PF_INET, SOCK_STREAM, pProtocol->p_proto);
    if (fd <= 0) {
        FATAL("Unable to create fd");
        return 0;
    }

    if (!SetFdNonBlock(fd)) {
        FATAL("Unable to put socket in non-blocking mode");
        return false;
    }

    TCPConnector<T> *pTCPConnector = new TCPConnector(fd, ip, port,
            protocolChain, customParameters);

    if (!pTCPConnector->Connect()) {
        IOHandlerManager::EnqueueForDelete(pTCPConnector);
        FATAL("Unable to connect");
        return false;
    }

    return true;
}

};

A: 

It should not matter. A class static function is about whether you need an instance of the class to call the function or not. Effectively, the primary difference between a non-static method and a static method is the former has an extra 'hidden' function parameter.

Since you are experiencing a crash, have you identified what part of the code is actually causing the crash?

R Samuel Klatchko
s/format/former/
Mike DeSimone
@MikeDeSimone - thanks.
R Samuel Klatchko
+1  A: 

I don't think the crash is related to the fact that you use templates, statics or inlining. At least in this particular case.

You should try to find out the cause of the crash, e.g. by analyzing the dump.

David Alfonso
+1  A: 

You hint that you think the library contains that function. Check if it does. If so, it is definitely an error.

Check that you have the right version of the headers for your library file.

Failing that, the fix to be able to use the library would probably be to erase the definition from the header so it isn't inline any more. That would effectively make it an extern (not export) templated function, so you would only be able to use specialization(s) in the library .o.

As for what you're wondering, a static member function is linked much the same as a free function. If it's inline, it is not possible to call from the library file. Otherwise, static essentially means the same as extern: that there is only one copy, anywhere.

Potatoswatter
A: 

I agree with David Alfonso that the crash can be unrelated to the fact you use this 'library'.

Also this 'library' contains several problems not related to the crash:

  • It's unclear the purpose of the template parameter T. It doesn't used anywhere.
  • There are multiple memory and resource leaks in the Connect() method:
    • pProtocol and pTCPConnector are never deleted;
    • fd is never closed, because pTCPConnector isn't deleted.
valyala