我最近写了一些字符串例程的替代品(memcpy、memset 和 memmove)。我的理解是,如果在编译/链接行中指定了包含这些例程的库,这些将优先于同名的系统标准库例程。如果我已经错了,请告诉我!
这在我所做的所有测试中都能正常工作(通过反汇编验证存在正确的例程而 glibc 例程不存在),但进一步的测试发现了一个由此引起的奇怪中断:
1)用-g在同一个库中构建另一个文件(我一直在构建-O2)
2) 这个文件有一个显式调用 memset
3a) 如果编译时选项的工作方式是这个 memset 被 gcc 内联,那么一切正常
3b) 但是,如果这些选项禁用了本应内联的 memset 调用的内联,则该库将构建,但使用该库静态链接应用程序会导致重复符号链接器错误 - 该符号的另一个实例是系统库的 memset。
基本上我可以构建我的库的两个版本(100 个源文件),并且通过将一个目录中的 make CFLAGS 从 -O1 -g 更改为仅 -g 我可以在使用该库时触发链接器错误。
我可以使用工作版本,通过 nm 运行它,并看到它有许多对 memset 的未定义引用,包括链接到我的测试用例的例程 - 所以我知道它应该尝试在工作用例中解析 memset。当我将此与损坏库的 nm 输出进行比较时,我看到的只是一些额外的未定义的 memcpy 和 memset 引用。如果 memset 在第一种情况下(对我的例程)解决了,它应该在第二种情况下解决。
我还查看了详细的编译器输出并验证了两种情况下的链接行完全相同,除了这个库的路径。
这里有两个超级令人费解的事情(在无数其他问题中):
1)为什么构建的库中的文件 -O1 -g 链接与 -g 不同
2) 为什么用户库中的替换 memset 会与系统 memset 冲突
而对于大奖,1)如何导致2)