Let me show you something.
gcov shows you which lines of code were executed (##### lines were never touched - why was this?), and how many times.
Questions you need to ask yourself are
- are the numbers in line with expectations of how you understand the code is supposed to work.
- lines with hashes are untested lines; can you think of test cases to exercise them? If you can't, then ask why you have that code in the first place.
Code:
$ g++ -fprofile-arcs -ftest-coverage main.cpp
$ ./a.out free hello c++ foo faz
Tree:
free[1]
c++[1]
foo[1]
faz[1]
hello[1]
Alphabetical:
c++[1]
faz[1]
foo[1]
free[1]
hello[1]
$ gcov main.cpp
File 'main.cpp'
Lines executed:98.04% of 51
Creating 'main.cpp.gcov'
$ cat main.cpp.gcov
-: 0:Source:main.cpp
-: 0:Graph:main.gcno
-: 0:Data:main.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include <iostream>
-: 2:#include <string>
-: 3:#include <string.h>
-: 4:
-: 5:using namespace std;
-: 6:
-: 7:struct Tnode {
-: 8: char *word;
-: 9: int count;
-: 10: Tnode *left;
-: 11: Tnode *right;
-: 12:};
-: 13:
12: 14:Tnode *addNode(Tnode * root, string word)
-: 15:{
-: 16: Tnode *node;
12: 17: if (!root) {
5: 18: node = new Tnode;
5: 19: node->word = new char[64 + 1];
5: 20: strcpy(node->word, word.c_str());
5: 21: node->left = 0;
5: 22: node->right = 0;
5: 23: node->count = 1;
5: 24: return (node);
-: 25: }
-: 26:
7: 27: int cmp = strcmp(word.c_str(), root->word);
-: 28:
7: 29: if (cmp < 0) {
4: 30: root->left = addNode(root->left, word);
3: 31: } else if (cmp > 0) {
3: 32: root->right = addNode(root->right, word);
-: 33: } else {
#####: 34: root->count++;
-: 35: }
-: 36:
7: 37: return (root);
-: 38:}
-: 39:
-: 40:
11: 41:void printTree(Tnode * root, int indent)
-: 42:{
11: 43: if (!root) {
6: 44: return;
-: 45: }
-: 46:
10: 47: cout << string(indent, ' ') << root->word
10: 48: << "[" << root->count << "]" << endl;
5: 49: printTree(root->left, indent + 4);
5: 50: printTree(root->right, indent + 4);
-: 51:}
-: 52:
-: 53:
11: 54:void aPrintTree(Tnode * root)
-: 55:{
11: 56: if (!root) {
6: 57: return;
-: 58: }
-: 59:
5: 60: aPrintTree(root->left);
5: 61: cout << root->word << "[" << root->count << "]" << endl;
5: 62: aPrintTree(root->right);
-: 63:}
-: 64:
-: 65:
1: 66:void printTree(Tnode * root)
-: 67:{
1: 68: printTree(root, 0);
1: 69:}
-: 70:
-: 71:
11: 72:void freeTree(Tnode * root)
-: 73:{
11: 74: if (!root) {
6: 75: return;
-: 76: }
-: 77:
5: 78: freeTree(root->left);
5: 79: freeTree(root->right);
-: 80:
5: 81: delete[]root->word;
5: 82: delete root;
-: 83:}
-: 84:
1: 85:int main(int argc, char *argv[])
-: 86:{
1: 87: Tnode *root = 0;
-: 88:
2: 89: string word;
-: 90:
6: 91: for (int i = 1; i < argc; i++) {
5: 92: word = string(argv[i]);
5: 93: root = addNode(root, word);
-: 94: }
-: 95:
1: 96: cout << "Tree:" << endl;
1: 97: printTree(root);
-: 98:
1: 99: cout << "Alphabetical:" << endl;
1: 100: aPrintTree(root);
-: 101:
1: 102: freeTree(root);
4: 103:}
> One question: Do you think the code is doing that what it should do?
I'm not going to answer it, because it's something you need to be able to figure out for yourself.
What is all the evidence you have telling you?
- does it compile?
- does it run?
- does it produce expected output?
- how many tests have you done?
- how much of the code passes test coverage?
What do you think?