Tag: gcc

GCC动态链接libc static和其他一些库,重新访问?

以下问题是相关的,但不回答我的问题: 在GCC中链接部分静态和部分动态 将动态库链接到链接到其他静态库的静态库 GCC:静态链接只有一些库 gcc中共享库函数的静态链接 我之前提出了一个非常类似的问题,但是由于我开始的上一个问题在评论部分有些混乱而没有得到完全回答(但我将其标记为已回答,因为这是一项很好的努力并且至少部分地回答了它)我会问一个新问题。 问题是具体如何将libc链接为静态,同时动态链接其他库(例如libm)。 有人提出在第一个问题中无法做到,是真的吗? 如果是这样,那么知道为什么不是非常有趣。 甚至可以这样做吗? 有人发表评论(由于某种原因被删除,可能是不正确的?)这是可能的,但必须存在动态链接版本的libc,因为动态库需要它(例如动态libm将需要动态libc(?))。 这对我来说很好,但对我来说如何告诉GCC这样做并不明显,即在libc中链接为静态和动态。 我该怎么做(我做了几次尝试,有些会在后面的问题中展示)? 或者还有其他方法可以做我想要的吗? 我们首先看到通过简单地运行gcc test.c -lm,所有内容都是动态链接的,如下所示: $ gcc test.c -lm $ ldd a.out linux-vdso.so.1 (0x00007fffb37d1000) libm.so.6 => /lib64/libm.so.6 (0x00007f3b0eeb6000) libc.so.6 => /lib64/libc.so.6 (0x00007f3b0eb10000) /lib64/ld-linux-x86-64.so.2 (0x00007f3b0f1b0000) 要仅将libm链接为静态,同时允许libc保持动态,我们可以这样做(正如Z boson在前面提到的一个问题中指出的那样): $ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libm.a $ ldd a.out linux-vdso.so.1 (0x00007fff747ff000) libc.so.6 => /lib64/libc.so.6 (0x00007f09aaa0c000) /lib64/ld-linux-x86-64.so.2 (0x00007f09aadb2000) 但是,尝试链接libc static和libm动态的相同过程似乎不起作用: […]

未定义引用“仅一些math.h”函数

我有一个奇怪的问题。 数学库已添加到我的makefile中。 # include standard C library LDFLAGS += -lc # include standard math library LDFLAGS += -lm 在输出文件(.map)中,我可以看到所有内容都已正确链接: LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/nof\libgcc.a LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libc.a LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libm.a 当我做 z = pow((double) 2, (double) 3); 它工作正常。 但如果我测试另一个函数,如: double result = asin(x); 我去拿: undefined reference to `asin’ collect2: ld returned 1 exit status 怎么会这样? math.h中提供了pow和asin ,见下文: /* Non reentrant […]

为什么char的符号没有在C中定义?

C标准规定: ISO / IEC 9899:1999,6.2.5.15(第49页) char,signed char和unsigned char这三种类型统称为字符类型。 实现应将char定义为具有与signed char或unsigned char相同的范围,表示和行为。 确实gcc根据目标平台定义。 我的问题是,为什么标准会这样做? 除了可怕的和难以发现的错误之外,我看不到任何可能来自模糊类型定义的内容。 不仅如此,在ANSI C(C99之前)中,唯一的字节大小类型是char,因此使用char进行数学运算有时是不可避免的。 所以说“一个人永远不应该使用char来表示数学”并非如此。 如果是这种情况,更明智的决定是包括三种类型“ char , ubyte , sbyte ”。 有没有理由,或者它只是一些奇怪的向后兼容性问题,以便将坏(但常见)编译器定义为标准兼容?

使用-std = c99进行隐式声明

我收到这个警告:( – -std=c99 -pedantic ) warning: implicit declaration of function ‘strndup’ [-Wimplicit-function-declaration] 但我正在导入这些库: #include #include #include 所以呢?! 🙁 // file.c: #include “file.h” strndup(…) // file.h: #include #include #include

字符数组下标警告

当我使用char数组下标时,如下例所示: int main(){ char pos=0; int array[100]={}; for(pos=0;pos<100;pos++) printf("%i\n", array[pos]); return 0; } 我收到警告,我正在使用char数组下标: 警告:数组下标的类型为’char'[-Wchar-subscripts] 哪个好,因为我启用了此警告。 GCC手册说: -Wchar-subscripts如果数组下标的类型为“char”,则发出警告。 这是错误的常见原因,因为程序员经常忘记这种类型是在某些机器上签名的。 -Wall启用此警告。 因此,此警告应防止使用负数组索引。 我的问题是,为什么这个警告只在char上激活而在其他签名类型上也没有? 谢谢。

如何在SIGSEGV上使用_Unwind_Backtrace获取fullstacktrace

我通过代码处理SIGSEGV: int C() { int *i = NULL; *i = 10; // Crash there } int B() { return C(); } int A() { return B(); } int main(void) { struct sigaction handler; memset(&handler,0,sizeof(handler)); handler.sa_sigaction = handler_func; handler.sa_flags = SA_SIGINFO; sigaction(SIGSEGV,&handler,NULL); return(C()); } 处理程序代码是: static int handler_func(int signal, siginfo_t info, void* rserved) { const void* […]

如何告诉GCC指针参数总是双字对齐?

在我的程序中,我有一个函数,它做一个简单的向量加法c[0:15] = a[0:15] + b[0:15] 。 function原型是: void vecadd(float * restrict a, float * restrict b, float * restrict c); 在我们的32位嵌入式架构上,有一个加载/存储双字加载/存储选项,如: r16 = 0x4000 ; strd r0,[r16] ; stores r0 in [0x4000] and r1 in [0x4004] GCC优化器识别循环的向量性质并生成代码的两个分支 – 一个用于3个数组是双字对齐的情况(因此它使用双重加载/存储指令)而另一个用于数组的情况是字对齐的(它使用单个加载/存储选项)。 问题是地址对齐检查相对于加法部分是昂贵的,我想通过暗示编译器a,b和c总是8对齐来消除它。 是否有一个修饰符添加到指针声明中以告诉编译器? 用于调用此函数的数组具有aligned(8)属性,但它不会反映在函数代码本身中。 是否可以将此属性添加到函数参数中?

如何在GCC x86中使用RDTSC计算时钟周期?

使用Visual Studio,我可以从处理器读取时钟周期数,如下所示。 我如何与GCC做同样的事情? #ifdef _MSC_VER // Compiler: Microsoft Visual Studio #ifdef _M_IX86 // Processor: x86 inline uint64_t clockCycleCount() { uint64_t c; __asm { cpuid // serialize processor rdtsc // read time stamp counter mov dword ptr [c + 0], eax mov dword ptr [c + 4], edx } return c; } #elif defined(_M_X64) // Processor: […]

GNU C本机向量:如何广播标量,如x86的_mm_set1_epi16

我如何编写一个可移植的GNU C内置向量版本,它不依赖于x86 set1内在函数? typedef uint16_t v8su __attribute__((vector_size(16))); v8su set1_u16_x86(uint16_t scalar) { return (v8su)_mm_set1_epi16(scalar); // cast needed for gcc } 当然必须有一个更好的方式 v8su set1_u16(uint16_t s) { return (v8su){s,s,s,s, s,s,s,s}; } 我不想写一个用于广播单个字节的AVX2版本! 对于你想要分配给一个变量而不是仅仅用作二元运算符的操作数(这与gcc一起使用,见下文)的情况, 即使只是gcc-only或clang-only这个部分的答案也会很有趣 。 如果我想使用广播标量作为二元运算符的一个操作数,则可以使用gcc( 如手册中所述 ),但不能使用clang: v8su vecdiv10(v8su v) { return v / 10; } // doesn’t compile with clang 有了clang,如果我只针对x86并且只使用本机向量语法来让编译器为我生成模数乘法逆常数和指令 ,我可以写: v8su vecdiv_set1(v8su v) { […]

at&t asm inline c ++问题

我的代码 const int howmany = 5046; char buffer[howmany]; asm(“lea buffer,%esi”); //Get the address of buffer asm(“mov howmany,%ebx”); //Set the loop number asm(“buf_loop:”); //Lable for beginning of loop asm(“movb (%esi),%al”); //Copy buffer[x] to al asm(“inc %esi”); //Increment buffer address asm(“dec %ebx”); //Decrement loop count asm(“jnz buf_loop”); //jump to buf_loop if(ebx>0) 我的问题 我正在使用gcc编译器。 出于某种原因,我的缓冲区/ howmany变量在我的asm眼中是不确定的。 我不知道为什么。 我只想将缓冲区数组的起始地址移动到esi寄存器中,将每个元素复制到al寄存器时循环“howmany”次。