Thread: static lib madness

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    static lib madness

    When I compile this:
    Code:
    #include <iostream>
    #include <ctime>
    #include <cstring>
    #include <string>
    #include <fstream>
    #include <sstream>
    
    #define LGROPENFAIL 1
    #define LGRWRITEFAIL 2
    
    class logger {
    	public:
    		std::ofstream log;
    		logger(std::string fpath, std::string who, bool fatal, bool buffd);
    		template<typename T> logger& operator<< (const T &data);
    		void stamp();
    		~logger();
    	private:
    		std::string id;
    		bool fatal;
    		bool buffd;
    };
    
    logger::logger(std::string fpath, std::string who, bool fatal, bool buffd) {
    	log.open(fpath.c_str(), std::ios::app|std::ios::out);
    	this->fatal = fatal;
    	this->buffd = buffd;
    	if (log.rdstate() && fatal) throw LGROPENFAIL;
    	id = who;
    	stamp();
    	log << "LOGGER BEGIN.\n";
    	if (!buffd) log.flush();
    }
    
    
    template<typename T> logger& logger::operator<< (const T &data) {
    	std::stringstream oss;
    	oss << data;
    	log << oss.str();
    	if (!buffd) log.flush();
    	if (log.rdstate() && fatal) throw LGRWRITEFAIL;
    	return *this;
    }
    
    
    void logger::stamp() {
    	const time_t t = time(NULL);
    	char *ts = ctime(&t), *p = strrchr(ts,' ');
    	*(++p) = '\0';
    	log << ts << id << ": ";
    	if (log.rdstate() && fatal) throw LGRWRITEFAIL;
    }
    
    
    logger::~logger() {
    	stamp();
    	log << "LOGGER DONE.\n";
    	log.close();
    }
    
    using namespace std;
    
    int main() {
    	logger log("test.log", "tester", true, true);
    
    	log.stamp();
    	log << "hey" << 23 << "\n"; 
    
    	return 0;
    }
    Everything works just fine. However, if I compile the class seperately:
    logger.h
    Code:
    #include <ctime>
    #include <cstring>
    #include <string>
    #include <fstream>
    #include <sstream>
    
    #ifndef LGROPENFAIL
    	#define LGROPENFAIL 1
    	#define LGRWRITEFAIL 2
    #endif
    
    class logger {
    	public:
    		std::ofstream log;
    		logger(std::string fpath, std::string who, bool fatal, bool buffd);
    		template<typename T> logger& operator<< (const T &data);
    		void stamp();
    		~logger();
    	private:
    		std::string id;
    		bool fatal;
    		bool buffd;
    };
    logger.cpp
    Code:
    #include <logger.h>
    
    logger::logger(std::string fpath, std::string who, bool fatal, bool buffd) {
    	log.open(fpath.c_str(), std::ios::app|std::ios::out);
    	this->fatal = fatal;
    	this->buffd = buffd;
    	if (log.rdstate() && fatal) throw LGROPENFAIL;
    	id = who;
    	stamp();
    	log << "LOGGER BEGIN.\n";
    	if (!buffd) log.flush();
    }
    
    
    template<typename T> logger& logger::operator<< (const T &data) {
    	std::stringstream oss;
    	oss << data;
    	log << oss.str();
    	if (!buffd) log.flush();
    	if (log.rdstate() && fatal) throw LGRWRITEFAIL;
    	return *this;
    }
    
    
    void logger::stamp() {
    	const time_t t = time(NULL);
    	char *ts = ctime(&t), *p = strrchr(ts,' ');
    	*(++p) = '\0';
    	log << ts << id << ": ";
    	if (log.rdstate() && fatal) throw LGRWRITEFAIL;
    }
    
    
    logger::~logger() {
    	stamp();
    	log << "LOGGER DONE.\n";
    	log.close();
    }
    Compile:
    g++ -c -o logger.o logger.cpp
    ar rcs liblogger++.a logger.o


    Then use this:
    logger-demo.cpp
    Code:
    #include <logger.h>
    
    using namespace std;
    
    int main() {
    	logger log("test.log", "tester", true, true);
    
    	log.stamp();
    	log << "hey" << 23 << "\n"; 
    
    	return 0;
    }
    and compile:
    gcc logger-demo.cpp -llogger++

    I suddenly get:

    /tmp/ccDZcs1z.o: In function `main':
    logger-demo.cpp.text+0x24b): undefined reference to `logger& logger:perator<< <char [4]>(char const (&) [4])'
    logger-demo.cpp.text+0x257): undefined reference to `logger& logger:perator<< <int>(int const&)'
    logger-demo.cpp.text+0x264): undefined reference to `logger& logger:perator<< <char [2]>(char const (&) [2])'
    collect2: ld returned 1 exit status

    So this is all specifically to do with the one template func overloading <<. I've never had a problem creating a static lib in C before, and I can't find any distinct caveats regarding doing it in C++. Anyone know what the deal is? I'm hoping it's just a switch I can add..
    Last edited by MK27; 03-20-2010 at 12:54 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Define the function template in the header. Alternatively, you can use your favourite trick of defining it in another file that is not compiled but included in the header instead. A more comprehensive answer is given in this answer to the FAQ: How can I avoid linker errors with my template functions?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Alright, thot I was going CRAZY. Thanks as always.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. seg fault at vectornew
    By tytelizgal in forum C Programming
    Replies: 2
    Last Post: 10-25-2008, 01:22 PM
  3. LNK2001 ERROR!!! need help
    By lifeafterdeath in forum C++ Programming
    Replies: 7
    Last Post: 05-27-2008, 05:05 PM
  4. get keyboard and mouse events
    By ratte in forum Linux Programming
    Replies: 10
    Last Post: 11-17-2007, 05:42 PM
  5. using VC6 link VC7 static lib error
    By George2 in forum C++ Programming
    Replies: 5
    Last Post: 06-29-2006, 10:58 PM