Tag: gcc

检查特定gcc编译器的glibc版本

我的系统上安装了两个gcc编译器,一个是gcc 4.1.2 (默认),另一个是gcc 4.4.4 。 我如何检查gcc 4.4.4使用的libc版本,因为/lib/libc.so.6显示了gcc 4.1.2使用的glibc,因为它是默认的编译器。

退出的Syscall实现()

我写了一个简单的C程序,只调用exit()函数,但是strace说二进制文件实际上是调用exit_group,exit()是一个exit_group()包装器吗? 这两个function是否相同? 如果是这样,为什么编译器会选择exit_group()而不是exit()?

gcc`__thread`如何工作?

如何在gcc中实现__thread ? 它只是pthread_getspecific和pthread_setspecific的包装器吗? 使用我的程序使用posix API进行TLS,现在看到我的程序运行时的30%用在pthread_getspecific上,我感到很失望。 我在每个需要资源的函数调用的条目上调用它。 pthread_getspecific联优化之后,编译器似乎没有优化pthread_getspecific 。 因此,在内联函数之后,代码基本上一次又一次地搜索正确的TLS指针以获得返回的相同指针。 __thread会在这种情况下帮助我吗? 我知道C11中有thread_local ,但我所拥有的gcc还不支持它。 (但现在我看到我的gcc确实支持_Thread_local而不是宏。) 我知道我可以简单地测试并看到。 但是我现在必须去别的地方了,在我尝试重大改写之前,我想更好地了解一个function。

具有未定义结果的C代码,编译器生成无效代码(使用-O3)

我知道当你在C程序中做某些事情时,结果是不确定的。 但是,编译器不应该生成无效 (机器)代码,对吧? 如果代码做错了,或者代码生成了段错误或其他什么,那将是合理的…… 这应该根据编译器规范发生,还是编译器中的错误? 这是我正在使用的(简单)程序: int main() { char *ptr = 0; *(ptr) = 0; } 我正在使用-O3编译。 这不应该生成无效的硬件指令,对吧? 使用-O0 ,运行代码时会出现段错误。 这看起来更加明智。 编辑:它正在生成一个ud2指令……

如何在x86上捕获数据对齐错误(在Sparc上也称为SIGBUS)

即使在i386上,是否有可能捕获数据对齐错误? 也许通过设置i386特定的机器寄存器或类似的东西。 在Solaris-Sparc上我在这种情况下收到一个SIGBUS,但在i386上一切都很好。 环境: 32位应用程序 Ubuntu Karmic gcc / g ++ v4.4.1 编辑 :这就是为什么我这样问: 我们的应用程序在使用SIGBUS的Sol-Sparc上崩溃了。 出于调试的目的,我会尝试在i386平台上获得类似的行为。 我们的Sol-sparc机器非常慢,因此编译和调试需要很长时间。 我们的i386机器速度令人难以置信(8核,32G内存)。 即使在i386平台上,数据对齐错误也会带来性能损失。 因此,我想尽可能修复数据对齐错误。

C99不是GCC的默认C版本?

为什么GCC默认不编译C99? 我的意思是为什么每次编写C99代码时都需要添加–std = c99标志?

gcc检测静态库中的重复符号/函数

我们有什么方法可以让gcc检测静态库中的重复符号与主代码(或另一个静态库?) 这是情况: main.c错误地包含一个函数定义,例如使用签名uint foohash(const char*) foo.c还包含一个带有签名uint foohash(const char*)的函数定义uint foohash(const char*) foo.c和其他源文件被编译为静态util库,主程序链接在其中,例如: gcc -o main main.o util.o -L ./libs -lfooutils 所以,现在main.o和libs / libfooutils.a都包含一个foohash函数。 据推测,链接器在main.o中找到了这个符号,并且不会在其他地方寻找它。 有什么方法可以让gcc检测到这种情况吗?

查询gcc的-ffunction-section和-fdata-sections选项

以下在GCC页面中提到的function部分和数据部分选项: -ffunction-sections -fdata-sections 如果目标支持任意节,则将每个函数或数据项放入输出文件中的自己的部分。 函数名称或数据项名称确定输出文件中节的名称。 在链接器可以执行优化以改善指令空间中引用的局部性的系统上使用这些选项。 大多数使用ELF对象格式的系统和运行Solaris 2的SPARC处理器都具有这种优化的链接器。 AIX可能会在将来进行这些优化。 只有在这样做的重大好处时才使用这些选项。 指定这些选项时,汇编器和链接器将创建更大的对象和可执行文件,并且速度也会更慢。 如果指定此选项,则无法在所有系统上使用gprof,如果同时指定此选项和-g,则可能在调试时遇到问题。 我的印象是这些选项有助于减少可执行文件的大小。 为什么这个页面会说它会创建更大的可执行文件? 我错过了什么吗?

在GCC中生成没有cmp指令的循环

我有一些紧凑的循环,我正在尝试使用GCC和内在函数进行优化。 考虑例如以下function。 void triad(float *x, float *y, float *z, const int n) { float k = 3.14159f; int i; __m256 k4 = _mm256_set1_ps(k); for(i=0; i<n; i+=8) { _mm256_store_ps(&z[i], _mm256_add_ps(_mm256_load_ps(&x[i]), _mm256_mul_ps(k4, _mm256_load_ps(&y[i])))); } } 这会产生这样的主循环 20: vmulps ymm0,ymm1,[rsi+rax*1] 25: vaddps ymm0,ymm0,[rdi+rax*1] 2a: vmovaps [rdx+rax*1],ymm0 2f: add rax,0x20 33: cmp rax,rcx 36: jne 20 但是cmp指令是不必要的。 而不是让rax从零开始并在sizeof(float)*n处完成,我们可以将基本指针( rsi […]

25:警告:初始化元素不是常量表达式

GCC在尝试编译时给出了以下警告消息: las.c:13:18: warning: initializer element is not a constant expression [enabled by default] const int ROWS = pow (2, MESH_K); 相关的代码部分是: #define MESH_K 10 #define BUFF_SIZE 30 const int ROWS = pow (2, MESH_K); 我需要在代码的后续点使用MESH_K和ROWS。 我理解函数调用可能导致GCC认为这不是一个常量表达式。 然而,鉴于对pow的调用本质上是一个常量,是否有更好的方法来实现它(可能是预处理器宏?)并消除警告? 我不介意在这部分代码中牺牲性能的可读性,因此欢迎任何和所有复杂的解决方案。