我的问题可归纳如下:
bar.c:
#include <stdio.h>
void bar() {
printf("bar\n");
}
Run Code Online (Sandbox Code Playgroud)
main.c:
#include <stdio.h>
void __attribute__((weak)) bar() {
printf("foo\n");
}
int main() {
bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Makefile:
all:
gcc -c bar.c
ar -rc libbar.a bar.o
gcc main.c -L. -lbar
Run Code Online (Sandbox Code Playgroud)
输出:
$ ./a.out
foo
Run Code Online (Sandbox Code Playgroud)
所以main.c中的弱符号栏不会被bar.c中的强符号覆盖,因为bar.c被链接到静态库libbar.a中的main.c.
我如何告诉gcc在libbar.a中使用强符号来覆盖main.c中的弱符号?
只是好奇.这显然不是一个非常好的实际编程解决方案,但是我想在Bless(十六进制编辑器)中创建一个可执行文件.
我的架构是x86.我能制作一个非常简单的程序是什么?你好世界?无限循环?与此问题类似,但在Linux中.
我正在使用基于处理器功能的CPU调度来切换复杂数值算法的实现.我想包括两个版本(sse2和sse3版本的参数)我正在同一个动态库中编译.
迄今所采取的方法是包装所有架构特定的代码放到一个命名空间如namespace sse2和namespace sse3,从而连接成最终的动态库时避免重复的符号名.
但是,如果我std::vector<int>在sse2和ss3版本中使用我的控件之外的某些代码(例如a )会发生什么.据我所知,std::vector实现将出现在sse2和sse3目标文件中,但理论上可能包含不同的指令,具体取决于编译器执行的优化.当我将这些目标文件链接到动态库时,将使用其中一个,我冒险尝试在仅支持sse2的cpu上运行sse3指令.
除了编译到两个独立的动态库之外,还可以做些什么来解决这个问题呢?我需要一个解决方案,在Windows,Mac OS和Linux上使用Visual Studio和clang.
考虑下面的简单程序:
__attribute__((weak)) void weakf(void);
int main(int argc, char *argv[])
{
weakf();
}
Run Code Online (Sandbox Code Playgroud)
当用 gcc 编译它并在 Linux PC 上运行它时,它会出现段错误。在 ARM CM0 (arm-none-eabi-gcc) 上运行它时,链接器通过跳转到以下指令和 nop 替换未定义的符号。
这种行为记录在哪里?是否有可能通过命令行选项更改它?我已经通过GCC和LD文档,没有关于这方面的信息。
但是,如果我检查 ARM 编译器文档,则会清楚地解释这一点。
这是我得到的情景.我正在测试的函数有一个错误条件,如果命中,它会调用一个正常的退出函数来释放任何全局内存,关闭句柄并退出程序.
显然,我想写一个测试,发现这个条件,以确保它被正确处理,但我不希望优雅的退出例程实际退出程序,因为这将停止任何剩余的测试.这意味着剔除优雅的退出例程.存根而不是调用exit的问题是控制流返回到被测函数(由于例程应该退出,这是不好的).
这是一个实际的问题:我们如何将控制从短线函数返回到测试而不是被测试的函数?
我可以做一个setjmp/longjmp,但由于"gotos"一般不好,我会喜欢任何其他的建议.(请记住,这是程序C,而不是C++,因此就我所知,异常不起作用)
编辑 正如索伦和其他人在下面提出的那样,当测试是一个好主意时,退出时什么都不做.无论是通过#define语句还是通过exit()例程的存根,有几种方法可以做到这一点.
但是,这样做会带来我真正解决问题的问题(除了setjmp/longjmp).看看这个场景:
void gracefulExit() {
// Clean Up
exit();
}
void routineUnderTest() {
// Do some calcs
if (someBadCondition == TRUE)
gracefulExit()
// Do some more calcs
}
Run Code Online (Sandbox Code Playgroud)
如果exit()在这种情况下什么都不做,gracefulExit()会将控制权返回给测试中的例程,这不应该发生.因此,我需要一种方法使exit()(或gracefulExit()的存根版本)将控制返回到测试而不是测试中的函数.
setjmp/longjmp(又名goto)是一种方法,虽然不是一种优雅的方式.关于如何解决这个问题的任何想法?
编辑#2
正如fizzer所提到的,setjmp/longjmp是处理这种情况的有效方法.这是我永久处理它的可能方式.
但是,我从同事那里得到了另一种可能的解决方案.而不是将gracefulExit()例程#defining到存根例程,请执行以下操作:
#define gracefulExit return NULL
Run Code Online (Sandbox Code Playgroud)
正在测试的特定函数处理这个很好,因为NULL是它的有效返回值.我还没有在每种可能的情况下对此进行测试(例如,具有void返回值的函数).如前所述,我可能会使用setjmp/longjmp方法来解决这个问题,但如果这个额外的解决方案为某人提出了一个想法,那太好了!
弱连接的便携性如何?
#pragma weak my_symbol
Run Code Online (Sandbox Code Playgroud)
我看到了这个问题: 如何制作 - 弱 - 链接 - 工作与gcc讨论如何使其工作.但有没有一个很好的方法来做到这一点,不需要gcc?
弱链接和用#ifdef保护声明有什么区别?
#ifndef my_weak_fn
void my_weak_fn(){/* Do nothing */ return;}
#endif
Run Code Online (Sandbox Code Playgroud) c ×4
gcc ×3
ld ×2
linker ×2
weak-linking ×2
arm ×1
assembly ×1
c++ ×1
elf ×1
linux ×1
portability ×1
simd ×1
unit-testing ×1
weak ×1