由内联函数引起的一个BUG

假定有三个文件inline.h, inline.cpp, main.cpp,内容如下:

inline.h类CPeople定义如下,其中包含一个内联函数SetHouse

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#ifndef __INLINE_H__
#define __INLINE_H__
#include <iostream>

class CPeople {
public:
    CPeople(int age, bool bHouse, int* p);
    ~CPeople();

    void SetHouse(bool bStatus) { m_hasHouse = bStatus; }

    void Show() const;
private:
    int m_age;
    //bool m_hasCar;
    bool m_hasHouse;
    int* m_pNull;
};

#endif

inline.cpp类CPeople的实现。成员函数Show仅仅是方便调试下断点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include "inline.h"

CPeople::CPeople(int age, bool bHouse, int* p)
: m_age(age)
//, m_hasCar(false)
, m_hasHouse(bHouse)
, m_pNull(p)
{
}


CPeople::~CPeople()
{
}


void CPeople::Show() const
{
    // just for debug
    std::cout << m_age << std::endl;
}

main.cpp中创建一个实例,并调用被实现为内联的成员函数SetHouse

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include "inline.h"

int main(int argc, const char *argv[])
{
    CPeople cI(10, false, NULL);

    cI.SetHouse(true);
    cI.Show();
    return 0;
}

Makefile是这样的:(请特别注意Makefile)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#CXXFLAGS = -g -std=c++11
CXXFLAGS = -std=c++11
LIBS = inline.o main.o
TARGETS = main

all: $(TARGETS)

main: $(LIBS)
	g++ $(CXXFLAGS) $^ -o $@

inline.o: inline.cpp inline.h
	g++ $(CXXFLAGS) inline.cpp -c -o $@

clean:
	rm -f $(LIBS) $(TARGETS)

首先我们运行make命令编译代码:

1
2
3
4
make
g++ -g -std=c++11 inline.cpp -c -o inline.o
g++ -g -std=c++11   -c -o main.o main.cpp
g++ -g -std=c++11 inline.o main.o -o main

请注意上面make的输出,编译得到了inline.omain.o,然后将两者链接得 到main

运行main在”inline.cpp“的20行放置断点,那么成员变量的值分别为?用GDB 看一下实际输出:

(gdb) p \*this
$1 = {m_age = 10, m_hasHouse = true, m_pNull = 0x0}

你答对了吗?

接下来,将类CPeople中的变量m_hasCar注释去掉,再编译:

1
2
3
make
g++ -g -std=c++11 inline.cpp -c -o inline.o
g++ -g -std=c++11 inline.o main.o -o main

看仔细了,make的输出有什么问题吗?

再用GDB调试main,同样在inline.cpp的第20行放置断点,看看此时的 成员变量值:

(gdb) p \*this
$1 = {m_age = 10, m_hasCar = true, m_hasHouse = false, m_pNull = 0x0}

你发现问题了吗?

成员函数SetHouse修改的应该是m_hasHouse的值,结果却是m_hasCar的值变了。出现BUG呢!!!

这是为什么呢?