由内联函数引起的一个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.o和main.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呢!!!
这是为什么呢?