11/09/2009

When I throw an exception, my program terminates with a “terminate called after throwing an instance of `…'” message

Answer

The function that throws the exception was called from C code, or code that was otherwise compiled without unwinding information. This affects gcc but not Visual C++: Visual C++ always generates full unwinding information.

If you can recompile the C code in question, recompile it with the –fexceptions flag: this will enable the generation of unwinding information (disabled by default for C).

If you cannot recompile the C code in question (for example, if it’s a system library), then you cannot throw exceptions when it calls your C++ code.

When I catch an exception, the exception message is always “Unknown exception” or “std::exception” instead of the correct message

Answer

You are catching std::exception (or another exception base class) by value. Catch by reference instead, to correctly catch instances of derived classes.

This code will print “Unknown exception” (Visual C++) or “std::exception” (GNU g++):

#include <stdexcept>
#include <iostream>

int main()
{
    try
    {
        throw std::runtime_error("error message");
    }
    catch(std::exception e)
    {
        std::cout << e.what() << std::endl;
    }
}

This code will correctly print “error message”:

#include <stdexcept>
#include <iostream>

int main()
{
    try
    {
        throw std::runtime_error("error message");
    }
    catch(std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}

11/07/2009

GNU make fails on Windows with “multiple target patterns” or “target pattern contains no `%'”

Answer

You have a quoted Win32 absolute path in a makefile rule. Don’t use quotes: GNU make doesn’t support quoting at all, and you will never be able to use paths with spaces in them in GNU make.

This is correct:

target: X:\path\to\file
	@command $< $@

This will raise an error:

target: "X:\path\to\file"
	@command $< $@
Why only absolute paths?

It’s the colon after the drive letter. The colon is a special character that tells GNU make that the rule is a pattern rule.

Why only quoted Win32 paths? why not unquoted paths?

GNU make has special code for recognizing and parsing Win32 paths. Since GNU make doesn’t support quoted paths, the opening quote is interpreted as just another character of the file name, the colon is no longer the second character of the path and the path is not recognized as a Win32 path.