Tag: gcc

使用内存屏障强制按顺序执行

试着继续我的想法,使用软件和硬件内存障碍我可以禁用编译器优化编译的代码中的特定函数的无序优化,因此我可以使用像Peterson这样的算法实现软件信号量或者Deker不需要无序执行,我测试了以下代码,其中包含SW barrier asm volatile(“”: : :”memory”) __sync_synchronize asm volatile(“”: : :”memory”)和gcc builtin HW barrier __sync_synchronize : #include int main(int argc, char ** argv) { int x=0; asm volatile(“”: : :”memory”); __sync_synchronize(); x=1; asm volatile(“”: : :”memory”); __sync_synchronize(); x=2; asm volatile(“”: : :”memory”); __sync_synchronize(); x=3; printf(“%d”,x); return 0; } 但编译输出文件是: main: .LFB24: .cfi_startproc subq $8, %rsp […]

64位GCC混合32位和64位指针

尽管代码有效,但我对编译器决定混合使用相同类型的32位和64位参数感到困惑。 具体来说,我有一个接收三个char指针的函数。 查看汇编代码,三个中的两个作为64位指针(如预期的那样)传递,而第三个,一个本地常量,但仍然是字符串,作为32位指针传递。 我看不出我的函数在第3个参数不是满载的64位指针时怎么知道。 显然,只要较高的一方为0,它就没关系,但我认为它没有努力确保这一点。 在这个例子中,任何东西都可能在RDX的高端。 我错过了什么? 顺便说一下,接收函数假定它是一个完整的64位指针,并在输入时包含以下代码: movq %rdx, -24(%rbp) 这是有问题的代码: .LC4 .string “My Silly String” .text .globl funky_funk .type funky_funk, @function funky_funk: pushq %rbp movq %rsp, %rbp pushq %rbx subq $16, %rsp movq %rdi, -16(%rbp) ;char *dst 64-bit movl %esi, -20(%rbp) ;int len, 32 bits OK movl $.LC4, %edx ;<<<<—- why is it […]

从void *到char **的无效转换

自从我搞砸C代码以来已经有一段时间了。 我在使用gcc在Ubuntu下编译C代码时遇到以下错误。 我用来编译代码的命令是(如果这些错误是因为我正在使用的编译器,请告诉我如何让它消失): gcc -o runnable mycode.C 错误:从’void *’到’char **’的无效转换 第39行是: sequence=malloc(sizeof(char *)*seqNum); 序列声明为: char **sequence; seqNum声明为: int seqNum

gcc,make:如何禁用警告失败?

我正在尝试使用AVR微控制器和avr-ada构建gcc,我遇到了一个障碍,因为我的常规编译器对AVR所需的版本过于挑剔。 我收到以下警告,这反过来导致gcc或make报告错误: gcc -c -g -O2 -gnatpg -gnata -nostdinc -I- -I. -Iada -I../../gcc/ada ../../gcc/ada/exp_ch5.adb -o ada/exp_ch5.o exp_ch5.adb:177:16: warning: function “Has_Address_Clause” is not referenced make[2]: *** [ada/exp_ch5.o] Error 1 make[1]: *** [all-gcc] Error 2 make: *** [all] Error 2 有没有办法指示gcc或使警告不失败?

是否使用一个编译器与另一个编译器兼容创建静态c库

在我的例子中,我有一个使用代码源gcc定位arm cortex-m4构建的库。 我试图将该库链接到使用IAR编译器编译的项目。 是否可以这样做或者是否必须使用新工具重建库? 哪些因素会影响这个?

linux中的fork()行为

我试图了解叉子,并尝试在C中关注: #include #include void forker() { printf(“%d: A\n”,(int)getpid()); fork(); wait(); printf(“%d: B\n”,(int)getpid()); printf(“%d: C\n”,(int)getpid()); fork(); wait(); printf(“%d: D\n”,(int)getpid()); } int main(void) { forker(); return 0; } 当我编译并运行结果a.out时,这是我观察到的: > ./a.out 3560: A 3561: B 3561: C 3562: D 3561: D 3560: B 3560: C 3563: D 3560: D 但是,当我执行以下操作时: > ./a.out > t.txt 奇怪的事情发生了: > cat […]

ISO 8601:2004中的C预处理器__TIMESTAMP__

如何在ISO 8601:2004中更换__TIMESTAMP__ ? __TIMESTAMP__ Sat Jul 6 02:50:06 2013 VS __TIMESTAMP_ISO__ 2013-07-06T00:50:06Z

如何使用扩展的gcc程序集指定x87 FPU堆栈的破坏底部?

在我们的代码库中,我发现了这个代码片段,用于在x87上快速,朝向负无穷大1舍入: inline int my_int(double x) { int r; #ifdef _GCC_ asm (“fldl %1\n” “fistpl %0\n” :”=m”(r) :”m”(x)); #else // … #endif return r; } 我不是非常熟悉GCC扩展汇编语法,但是从我从文档中收集到的内容: r必须是一个记忆位置,我写回来的东西; x必须也是一个内存位置,数据来自哪里。 没有clobber规范,所以编译器可以放心,在代码片段的末尾,寄存器就像他离开时一样。 现在,提出我的问题:最终FPU堆栈是平衡的,但如果所有8个位置都已经在使用并且我已经溢出呢? 编译器如何知道它不能信任ST(7)离开它的位置? 应该添加一些clobber吗? 编辑我试图在clobber列表中指定st(7) ,它似乎影响codegen,现在我将等待对此事实的一些确认。 作为旁注:在glibc和MinGW中查看准系统lrint的实现我看到类似的东西 __asm__ __volatile__ (“fistpl %0” : “=m” (retval) : “t” (x) : “st”); 我们要求输入直接放在ST(0) (这避免了可能无用的fldl ); 什么是”st” clobber? 文档似乎只提到t (即堆栈的顶部)。 是的,它取决于当前的舍入模式,在我们的应用程序中应该总是“朝向负无穷大”。

宏依赖宏

有可能做这样的事情: #define F(x) \ #ifdef DOUBLE \ 2*x \ #else \ x \ #endif 所以当我使用F ,它扩展到什么取决于是否定义了宏DOUBLE ? 我不这么认为,但我很有希望。 GNU扩展很好。 编辑为了回答一些答案,我实际上是用它来做一些代码生成,其中代码略有不同,具体取决于它的定义位置。 由于包含某些文件的顺序以及需要定义相关宏的位置,以此方式切换它需要一些因子。 我可能不得不这样做,但如果我不必从这个角落重新点燃自己,我会很激动!

为什么GCC在获取void表达式的地址时开始发出警告?

在几个GCC版本之前,我可以做这样的事情: $ objcopy -I binary -O elf64-x86-64 -B i386 foo.png foo.png.o …在C中加入以下内容,作为SDL图像加载的示例: extern void _binary_foo_png_start; extern void _binary_foo_png_start; SDL_Surface *image = IMG_Load_RW(SDL_RWFromMem(&_binary_foo_png_start, &_binary_foo_png_end)); 然后我将foo.png.o与C文件中的目标文件链接起来,并获得一个整齐地包含foo.png的可执行文件。 这些天,我仍然可以这样做,但海湾合作委员会警告我: foo.c:57:19: warning: taking address of expression of type ‘void’ foo.c:57:44: warning: taking address of expression of type ‘void’ 显然它仍然有效,据我所知,它确实做到了它应该做的事情。 符号本身没有明确定义的类型,因此将它们声明为void似乎是合适的。 我的意思是,当然,我也可以给他们任何其他任意类型,它仍然可以正常工作,就像我只是想要他们的地址一样,但声明它们void似乎比组成某种类型更好。 那么为什么GCC突然决定开始警告我这个呢? 是否还有其他一些首选方式可以做到这一点?