Browsing all posts tagged c++

I recently ran into a stupid problem using the system() call in C++ on Windows platforms. For some strange reason, calls to system() get passed through the cmd /c command. This has some strange side effects if your paths contain spaces, and you try to use double quotes to allow those paths. From the cmd documentation:

If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters:
  1. If all of the following conditions are met, then quote characters on the command line are preserved:
    • no /S switch
    • exactly two quote characters
    • no special characters between the two quote characters, where special is one of: &<>()@^|
    • there are one or more whitespace characters between the two quote characters
    • the string between the two quote characters is the name of an executable file
  2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character.

As you can see from this documentation, if you have any special characters or spaces in your call to system(), you must wrap the entire command in an extra set of double quotes. Here's a working example:

string myCommand = "\"\"C:\\Some Path\\Here.exe\" -various -parameters\"";
int retVal = system(myCommand.c_str());
if (retVal != 0)
{
    // Handle the error
}

Note that I've got a pair of quotes around the entire command, as well as a pair around the path with spaces. This requirement isn't apparent at first glance, but it's something to keep in mind if you ever find yourself in this situation.

As I mentioned a while back, I've been wanting to discuss automatic dependency generation using GNU make and GNU gcc. This is something I just recently figured out, thanks to two helpful articles on the web. The following is a discussion of how it works. I'll be going through this material quickly, and I'll be doing as little hand-holding as possible, so hang on tight.

Let's start by looking at the final makefile:

SHELL = /bin/bash

ifndef BC
    BC=debug
endif

CC = g++
CFLAGS = -Wall
DEFINES = -DMY_SYMBOL
INCPATH = -I../some/path

ifeq($(BC),debug)
    CFLAGS += -g3
else
    CFLAGS += -O2
endif

DEPDIR=$(BC)/deps
OBJDIR=$(BC)/objs

# Build a list of the object files to create, based on the .cpps we find
OTMP = $(patsubst %.cpp,%.o,$(wildcard *.cpp))

# Build the final list of objects
OBJS = $(patsubst %,$(OBJDIR)/%,$(OTMP))

# Build a list of dependency files
DEPS = $(patsubst %.o,$(DEPDIR)/%.d,$(OTMP))

all: init $(OBJS)
    $(CC) -o My_Executable $(OBJS)

init:
    mkdir -p $(DEPDIR)
    mkdir -p $(OBJDIR)

# Pull in dependency info for our objects
-include $(DEPS)

# Compile and generate dependency info
# 1. Compile the .cpp file
# 2. Generate dependency information, explicitly specifying the target name
# 3. The final three lines do a little bit of sed magic. The following
#    sub-items all correspond to the single sed command below:
#    a. sed: Strip the target (everything before the colon)
#    b. sed: Remove any continuation backslashes
#    c. fmt -1: List words one per line
#    d. sed: Strip leading spaces
#    e. sed: Add trailing colons
$(OBJDIR)/%.o : %.cpp
    $(CC) $(DEFINES) $(CFLAGS) $(INCPATH) -o $@ -c $<
    $(CC) -MM -MT $(OBJDIR)/$*.o $(DEFINES) $(CFLAGS) $(INCPATH) \
        $*.cpp > $(DEPDIR)/$*.d
    @cp -f $(DEPDIR)/$*.d $(DEPDIR)/$*.d.tmp
    @sed -e 's/.*://' -e 's/\\\\$$//' < $(DEPDIR)/$*.d.tmp | fmt -1 | \
        sed -e 's/^ *//' -e 's/$$/:/' >> $(DEPDIR)/$*.d
    @rm -f $(DEPDIR)/$*.d.tmp

clean:
    rm -fr debug/*
    rm -fr release/*

Let's blast through the first 20 lines of code real quick, seeing as this is all boring stuff. We first set our working shell to bash, which happens to be the shell I prefer (if you don't specify this, the shell defaults to 'sh'). Next, if the user didn't specify the BC environment variable (short for "Build Configuration"), we default it to a value of 'debug.' This is how I gate my build types in the real world; I pass it in as an environment variable. There are probably nicer ways of doing this, but I like the flexibility that an environment variable gives me. Next, we set up a bunch of common build variables (CC, CFLAGS, etc.), and we do some build configuration specific setup. Finally, we set our DEPDIR (dependency directory) and OBJDIR (object directory) variables. These will allow us to store our dependency and object files in separate locations, leaving our source directory nice and clean.

Now we come to some code that I discussed in my last programming grab bag:

# Build a list of the object files to create, based on the .cpps we find
OTMP = $(patsubst %.cpp,%.o,$(wildcard *.cpp))

# Build the final list of objects
OBJS = $(patsubst %,$(OBJDIR)/%,$(OTMP))

# Build a list of dependency files
DEPS = $(patsubst %.o,$(DEPDIR)/%.d,$(OTMP))

The OTMP variable is assigned a list of file names ending with the .o extension, all based on the .cpp files we found in the current directory. So, if our directory contained three files (a.cpp, b.cpp, c.cpp), the value of OTMP would end up being: a.o b.o c.o.

The OBJS variable modifies this list of object files, sticking the OBJDIR value on the front of each, resulting in our "final list" of object files. We do the same thing for DEPDIR, instead prepending the DEPDIR value to each entry (giving us our final list of dependency files).

Next up is our first target, the all target. It depends on the init target (which is responsible for making sure that the DEPDIR and OBJDIR directories exist), as well as our list of object files that we created moments ago. The command in this target will link together the objects to form an executable, after all the objects have been built. The next line is very important:

# Pull in dependency info for our objects
-include $(DEPS)

This line tells make to include all of our dependency files. The minus sign at the front says, "if one of these files doesn't exist, don't complain about it." After all, if the dependency file doesn't exist, neither does the object file, so we'll be recreating both anyway. Let's take a quick look at one of the dependency files to see what they look like, and to understand the help they'll provide us:

objs/myfile.o: myfile.cpp myfile.h
myfile.cpp:
myfile.h:

In this example, our object file depends on two files: myfile.cpp and myfile.h. Note that, after the dependency list, each file is listed by itself as a rule with no dependencies. We do this to exploit a subtle feature of make:

If a rule has no prerequisites or commands, and the target of the rule is a nonexistent file, then make imagines this target to have been updated whenever its rule is run. This implies that all targets depending on this one will always have their commands run.

This feature will help us avoid the dreaded "no rule to make target" error, which is especially helpful if a file gets renamed during development. No longer will you have to make clean in order to pick up those kinds of changes; the dependency files will help make do that work for you!

Back in our makefile, the next giant block is where all the magic happens:

# Compile and generate dependency info
# 1. Compile the .cpp file
# 2. Generate dependency information, explicitly specifying the target name
# 3. The final three lines do a little bit of sed magic. The following
#    sub-items all correspond to the single sed command below:
#    a. sed: Strip the target (everything before the colon)
#    b. sed: Remove any continuation backslashes
#    c. fmt -1: List words one per line
#    d. sed: Strip leading spaces
#    e. sed: Add trailing colons
$(OBJDIR)/%.o : %.cpp
    $(CC) $(DEFINES) $(CFLAGS) $(INCPATH) -o $@ -c $<
    $(CC) -MM -MT $(OBJDIR)/$*.o $(DEFINES) $(CFLAGS) $(INCPATH) \
        $*.cpp > $(DEPDIR)/$*.d
    @cp -f $(DEPDIR)/$*.d $(DEPDIR)/$*.d.tmp
    @sed -e 's/.*://' -e 's/\\\\$$//' < $(DEPDIR)/$*.d.tmp | fmt -1 | \
        sed -e 's/^ *//' -e 's/$$/:/' >> $(DEPDIR)/$*.d
    @rm -f $(DEPDIR)/$*.d.tmp

This block of code is commented, but I'll quickly rehash what's going on. The first command actually compiles the object file, while the second command generates the dependency file. We then use some sed magic to create the special rules in each dependency file.

Though it's a lot to take in, these makefile tricks are handy to have in your toolbox. Letting make handle the dependency generation for you will save you a ton of time in the long run. It also helps when you're working with very large projects, as I do at work.

If you have a comment or question about this article, feel free to comment.

It has once again been ages since the last programming grab bag article was published, so let's dive right into another one, shall we? This time around, we'll be looking at some simple tricks involving GNU make.

1. Let Make Construct Your Object List

One common inefficiency in many Makefiles I've seen is having a manual list of the object files you are interested in building. Let's work with the following example makefile (I realize that this makefile has a number of design issues; it's a simple, contrived example for the sake of this discussion). I've highlighted the list of objects below (line 2):

CFLAGS = -Wall
OBJS = class_a.o class_b.o my_helpers.o my_program.o

all: my_program

my_program: $(OBJS)
    gcc -o my_program $(OBJS)

class_a.o: class_a.cpp
    gcc $(CFLAGS) -c class_a.cpp

class_b.o: class_b.cpp
    gcc $(CFLAGS) -c class_b.cpp

my_helpers.o: my_helpers.cpp
    gcc $(CFLAGS) -c my_helpers.cpp

my_program.o: my_program.cpp
    gcc $(CFLAGS) -c my_program.cpp

For very small projects, maintaining a list like this is doable, even if it is a bother. When considering larger projects, this approach rarely works. Why not let make do all this work for us? It can generate our list of object files automatically from the cpp files it finds. Here's how:

OBJS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))

We are using two built-in functions here: patsubst and wildcard. The first function will do a pattern substitution: the first parameter is the pattern to match, the second is the substitution, and the third is the text in which to do the substitution.

Note that, in our example, the third parameter to the patsubst function is a call to the wildcard function. A call to wildcard will return a space separated list of file names that match the given pattern (in our case, *.cpp). So the resulting string in our example would be: class_a.cpp class_b.cpp my_helpers.cpp my_program.cpp. Given this string, patsubst would change all .cpp instances to .o instead, giving us (at execution time): class_a.o class_b.o my_helpers.o my_program.o. This is exactly what we wanted!

The obvious benefit of this technique is that there's no need to maintain our list anymore; make will do it for us!

2a. Use Pattern Rules Where Possible

One other obvious problem in our example makefile above is that all the object targets are identical in nature (only the file names are different). We can solve this maintenance problem by writing a generic pattern rule:

%.o: %.cpp
    gcc -c $< -o $@

Pretty ugly syntax, huh? This rule allows us to build any foo.o from a corresponding foo.cpp file. Again, the % characters here are wildcards in the patterns to match. Note also that the command for this rule uses two special variables: $< and $@. The former corresponds to the name of the first prerequisite from the rule, while the latter corresponds to the file name of the target of this rule.

Combining this pattern rule with the automatic list generation from tip #1 above, results in the following updated version of our example makefile:

CFLAGS = -Wall
OBJS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))

all: my_program

my_program: $(OBJS)
    gcc -o my_program $(OBJS)

%.o: %.cpp
    gcc $(CFLAGS) -c $< -o $@

This is much more maintainable than our previous version, wouldn't you agree?

2b. Potential Problems With This Setup

Astute readers have undoubtedly noticed that my sample makefile has no header (.h) files specified as dependencies. In the real world, it's good to include them so that updates to said files will trigger a build when make is executed. Suppose that our example project had a header file named class_a.h. As the makefile is written now, if we update this header file and then call make, nothing will happen (we would have to make clean, then make again, to pick up the changes).

Header file dependencies aren't likely to be a one-to-one mapping. Fortunately, we can get make to automatically generate our dependencies for us. Furthermore, we can get make to include those automatic dependencies at execution time, without any recursive calls! The process for doing this is above and beyond the scope of this article, but I will be writing an article on this very subject in the near future (so stay tuned).

3. Target-Specific Variables Can Help

Suppose that we want to build a debug version of our program using a target. Wouldn't it be nice to be able to modify some of our variable values given that specific target? Well, it turns out that we can do just that. Here's how (the added lines have been highlighted):

CFLAGS = -Wall
OBJS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))

all: my_program

debug: CFLAGS += -g3
debug: my_program

my_program: $(OBJS)
    gcc -o my_program $(OBJS)

%.o: %.cpp
    gcc -c $< -o $@

In this example, when we type make debug from the command line, our CFLAGS variable will have the appropriate debug option appended (in this case, -g3), and then the program will be built using the specified dependencies. Being able to override variables in this manner can be quite useful in the right situations.

Do you have your own make tips? If so, leave a comment! I'll be posting more about doing automatic dependency generation with make and gcc in the near future.

Before we get to the meat of this article, here's a quick introductory story. The next release of Paper Plus will only allow one instance of the application to run at a time. One strange bug I ran into during the testing phase of this new feature, was the case where the application was minimized to the system tray. If a previous instance is already running (and minimized), I wanted the action of trying to start a new instance to restore the old one. For a number of reasons which I won't go into, I couldn't get the level of control I needed to restore things properly. So, to get things working, I turned to user defined messages which, happily, solved my problem. Here's a quick guide to getting custom messages up and running in a Visual C++ application.

Step 1: Define the Message ID

This is straightforward, but you'll need to make sure your definition appears in the appropriate place. I put mine in stdafx.h, which is included by nearly every file in the project.

#define WM_MYCUSTOMMESSAGE WM_USER+1

Step 2: Add the Message to a Message Map

Next, your custom message needs to be added to the appropriate message map. I added mine to the message map down in my CFrameWnd derived class. Here's how the entry looks in my case:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
...
ON_MESSAGE(WM_MYCUSTOMMESSAGE, MyCustomCallback)
...
END_MESSAGE_MAP()

Step 3: Implement the Custom Callback

Your callback function declaration must adhere to the appropriate form, as shown below:

LRESULT MyCustomCallback(WPARAM wParam, LPARAM lParam);

Custom message callbacks must always return an LRESULT, and must accept two parameters: a WPARAM and an LPARAM (down under the covers, both are simply pointers of varying types).

Once you've got the declaration in place, it's time for the definition:

LRESULT CMainFrame::MyCustomCallback(WPARAM wParam, LPARAM lParam)
{
    // Do something clever here
    return 0; // Make sure to return some value
}

Step 4: Post Your Custom Message

Now that we've got our custom message callback installed, we need to post our new message in the appropriate place. I decided to use the SendMessageTimeout function, based on some code I saw which used this function to prevent the application from hanging. Here's a variant of the code I used:

DWORD_PTR dwResult = 0;
// The hWnd parameter below is a handle to the window this message
// should be posted to. Setting this up is not shown, in order to keep
// this article as short as possible.
SendMessageTimeout(hWnd, WM_MYCUSTOMMESSAGE, 0, 0,
                   SMTO_ABORTIFHUNG, 5000, &dwResult);

And that's it! Being able to post your own messages can help you out of some sticky situations, and lets you take control of your application in some interesting new ways.

I ran into a weird problem in one of our build scripts at work today. We compile our tools across a number of platforms and architectures, and I ran across this issue on one of our oldest boxes, running RedHat 9. Here's the horrible error that I got when linking:

/usr/bin/ld: myFile.so: undefined versioned symbol name std::basic_string<char, std::char_traits<char>, std::allocator<char> >& std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_safe<char const*>(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char const*, char const*)@@GLIBCPP_3.2 /usr/bin/ld: failed to set dynamic section sizes: Bad value

It seems as if the standard C++ libraries on this system were compiled with gcc 3.2, while the version we're using to build our tools is 3.2.3. Unfortunately, the 3.2 compiler isn't installed on the system, and I'm not sure where we would find it for RH9 anyway. Thankfully, I found a workaround for this problem. Our link step originally looked like this:

gcc -shared -fPIC -lstdc++ -lrt -lpthread -o myFile.so {list_of_object_files}

I found out that by moving the standard libraries to the end of the line, the problem disappeared. Here's the new link step:

gcc -shared -fPIC -o myFile.so {list_of_object_files} -lstdc++ -lrt -lpthread

I don't fully understand why ordering should matter during the link step, but by putting the standard libraries last, we were able to get rid of this error. If you understand the root cause of this, please leave a comment explaining. I'd love to know more about why changing the order makes a difference.

C++ is Broken

Jul 11, 2005

I do a fair amount of C++ programming these days, thanks to my new career at IBM. C++ is my strongest language, and the first language I picked up when I began programming. As such, it's fairly special to me. However, the more I time I spend with C++, the more I come to see how broken it is.

For instance, why are strings not a base type? Character arrays simply do not suffice. I am aware of the STL string class (and I make use of it), but adding on this capability after the fact seems cheap. Strings should be a first-class object, and should have all the associated operators directly available (==, +=, etc.). And regular expressions should be directly available for strings, since they are so incredibly useful. There are tons of places in my code where access to regular expressions would make my life profoundly simple. For example, take Perl's match operator (m//). How many Perl programs out there do not make use of this operator? My guess is that the number is very low. It's no different in C++; reg-exes could be used all over the place.

Other glaring omissions also crop up. Where is the foreach loop construct? Why use #include instead of packages or modules? Where are the array operators (shift, unshift, pop, push)?

There's no question that C++ is a robust language. It's fast, gives the programmer complete control (both a blessing and a curse), and it has an incredible user base (which results in excellent support when you need it). But it's clearly dated. Will we still hold on to this language in 20 years? Or will something innovative finally come along to push it aside? Let's hope for the latter.