
Legal:
This document is copyright © 2002 Jim Brooks.
Permission to copy, distribute, link, and reformat is given on condition that authorship is indicated.
time myprogramgcc -s -Osld -sint limit = 0100; /* oops, limit is assigned 64 (decimal) */
if ( x & MASK == VALUE ) /* WRONG: equivalent to (x & (MASK==VALUE)) */ if ( (x & MASK) == VALUE ) /* right */
char* foo( void )
{
char str[100];
[..]
return str; /* WRONG, points within temporary stack */
}
The body of a macro and every parameter should be parenthesized to prevent surreptitious precedence bugs:
#define MAX(a,b) a > b ? a : b /* WRONG */ /* WRONG: result=1 (0xffff vs. y because '>' has more precedence than '&') */ x = 1; y = 2; result = MAX(x & 0xffff, y);TRUE is #defined as 1 but TRUE is logically any non-zero value:
if ( result == TRUE ) /* WRONG */ if ( result ) /* correct, if result != 0 */
for (i=0; i<MAX; ++i)
{
no_match:
for (j=0; j<MAX; ++j )
{
if ( !match )
goto no_match;
}
}
The above code is incorrect. goto skips the incrementing of i
for (i=0; i<MAX; ++i)
{
for (j=0; j<MAX; ++j )
{
if ( !match )
goto no_match;
}
no_match:
}
cout << typeid(int).name() << "\n";
// WRONG: if ( strcmp( typeid(pObject).name(), "MyClass" ) == 0 ) ... // Correct: if ( typeid(pObject) == typeid(MyClass) ) ...
class MyClass
{
public:
MyClass( void ) : arr(arr_) { };
const int (&arr)[100]; // declare a reference to a const array
private:
int arr_[100];
};
gcc -s -Osld -sgdb -nwBoot or reset the target board, then give these commands
(gdb) set remotebaud 38400 (gdb) target remote /dev/ttyS0 (gdb) load myprogram
-oformat srec" to the linker ld.A powerful ability of GNU make that assists in automatically generating dependencies is that the same target can specified multiple times.
The first target tells make how to compile the .o file.
The second target tells make the dependencies of the .o file.
main.o:
gcc -c <so forth>
main.o: main.h common.h
The second target is an autogenerated depedency. In practice, it will be written to an autogenerated file which will be included by the makefile, eg:
main.o: -include deps # "deps" is a file autogenerated by gcc -MM or makedepend
How is "deps" autogenerated? What will GNU make do if it doesn't exist?
Another ability of GNU make is that "-include <file>" implies dependency. For "-include deps", if "deps" doesn't exist, GNU make will execute its rule. Additionally:
main.o:
deps:
<gcc -M or makedepend>
-include deps
Either gcc or makedepend can autogenerate dependencies. Either can be passed a list of source files (to generate dependencies all-at-once).
Below are two examples. The first was written first and is based on GNU make documentation. The second is derived from Palomino and it uses separate source and object directories. gcc or makedepend could be substituted in either example.
1. Make object file depend on a "dependency file", conventionally suffixed as ".d".
Ie: *.o --> *.d --> *.c
2. Create suffix rules similar to:
%.d: %.c
$(CC) -MM $< > $@
.c.o:
$(CC) -c -o $@ $<
3. Add this line to a makefile to include all of the dependency files:
include ${C_SRCS:.c=.d}
................................................................................
# Skeletal GNUmakefile that autogenerates dependencies using gcc.
# This is simple but the disadvantage is that is doesn't use
# separate source and object directories.
CC = g++
CC_SRCS = main.cc
all: main.o
clean:
rm -f *.o *.d
%.d: %.cc
$(CC) -MM $< > $@
.cc.o:
$(CC) -c -Wall -o $@ $<
include ${CC_SRCS:.cc=.d}
................................................................................
................................................................................
# Skeletal GNUmakefile (derived from Palomino) that autogenerates dependencies
# using makedepend and uses separate source and object directories.
CC_SRCS = main.cc
HH_SRCS = header.hh
OUT_DIR = out
SRC_DIR = src
SRC_EXT = .cc
INC_FLAGS = -I$(SRC_DIR)
CC = g++
CC_FLAGS = -Wall
# Order dependent.
CC_OBJS := $(addprefix $(OUT_DIR)/,$(CC_SRCS:$(SRC_EXT)=.o))
CC_SRCS := $(addprefix $(SRC_DIR)/,$(CC_SRCS))
HH_SRCS := $(addprefix $(SRC_DIR)/,$(HH_SRCS))
all: $(OUT_DIR) $(CC_OBJS)
$(OUT_DIR):
mkdir -p out
clean:
rm -f $(OUT_DIR)/*.o $(OUT_DIR)/deps
# Build an object file from every source file.
$(OUT_DIR)/%.o: $(SRC_DIR)/%$(SRC_EXT)
$(CC) -c -o $@ $(CC_FLAGS) $(subst $(OUT_DIR)/,$(SRC_DIR)/,$<)
# Skip depend rule if clean (-include would otherwise make it).
# Pass -I flags (INC_FLAGS) to makedepend or it will omit those directories.
# -include depends on $(OUT_DIR)/deps which make will make.
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
depend $(OUT_DIR)/deps: $(CC_SRCS) $(HH_SRCS)
@mkdir -p $(OUT_DIR)
makedepend $(INC_FLAGS) -Y -f- $(CC_SRCS) 2>/dev/null | sed 's/$(SRC_DIR)\//$(OUT_DIR)\//' > $(OUT_DIR)/deps
-include $(OUT_DIR)/deps
endif
................................................................................