这些MySQL类如何能够链接
How are these MySQL classes able to link?
在内置MySQL存储引擎的实现中,存在具有以下结构的类:
// omitting lots of code across several files
class handler {
protected:
virtual void notify_table_changed();
};
void handler::notify_table_changed() {
// implementation
}
class ha_innopart : public handler {
void notify_table_changed();
};
// NB: no implementation for ha_innopart!
据我了解,这应该会产生链接错误,因为ha_innopart
将缺少notify_table_changed()
的 vtable 条目。这得到了 gcc 常见问题解答的支持。
指向相关 MySQL 类的链接:
-
handler.h
: https://github.com/mysql/mysql-server/blob/67d52e7c7a1a23424e39273cbb6f5f9d56fda8d1/sql/handler.h#L3518-L3523 -
handler.cc
: https://github.com/mysql/mysql-server/blob/67d52e7c7a1a23424e39273cbb6f5f9d56fda8d1/sql/handler.cc#L4736-L4744 -
ha_innopart.h
: https://github.com/mysql/mysql-server/blob/67d52e7c7a1a23424e39273cbb6f5f9d56fda8d1/storage/innobase/handler/ha_innopart.h#L306-L307
如我所见,以下代码重现了该问题:
#include <stdio.h>
class A {
public:
virtual int foo();
};
class B : public A {
public:
int foo(); // Will work by commenting out this line...
};
int A::foo() { return 42; }
// int B::foo() { return 24; } // ...or uncommenting this line.
int main(int argc, char **argv) {
B b;
::printf("%dn", b.foo());
}
编译它得到:
$ g++ test.cc -o test && ./test
/tmp/ccAiCHry.o: In function `main':
test.cc:(.text+0x32): undefined reference to `B::foo()'
/tmp/ccAiCHry.o: In function `B::B()':
test.cc:(.text._ZN1BC2Ev[_ZN1BC5Ev]+0x1f): undefined reference to `vtable for B'
collect2: ld returned 1 exit status
如上面的评论中所写,这个问题可以通过注释掉B
的foo()
声明或通过为B
提供foo()
的实现来解决。这些案例的输出分别是:
$ !!
g++ test.cc -o test && ./test
42
$ !!
g++ test.cc -o test && ./test
24
那么,为什么MySQL没有实现ha_innopart::notify_table_changed()
并且仍然能够编译和链接而不会出错呢?
事实证明,ha_innopart
的实现被分解在几个文件中,并且实现确实存在:
-
handler0alter.cc
: https://github.com/mysql/mysql-server/blob/67d52e7c7a1a23424e39273cbb6f5f9d56fda8d1/storage/innobase/handler/handler0alter.cc#L8927-L8938
我在搜索用途时找到了实现。
https://github.com/mysql/mysql-server/search?utf8=%E2%9C%93&q=notify_table_changed
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- CMake-按正确顺序将项目与C运行时对象文件链接
- 从链接列表c++中删除一个项目
- 有根的二进制搜索树.保留与其父级的链接
- 读取文件的最后一行并输入到链接列表时出错
- 静态数据成员的问题-修复链接错误会导致编译器错误
- node-gyp 在 macOS 上未正确链接库
- 基于boost的程序的静态链接——zlib问题
- 无法链接 CMake 中的本地库
- 内联函数中具有内部链接的全局变量
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 使用gcc从静态链接的文件中查找可选符号
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 下面是我为检测链接列表中的循环而制作的代码
- 有了gcc,是否可以链接库,但前提是它存在
- 使用C链接在函数内部创建C++模板
- 这些MySQL类如何能够链接
- 能够在没有pthreads的情况下链接,并且程序仍然运行
- 我如何能够链接以下数据