Tag: 编译器构造

为什么gcc反汇编程序为局部变量分配额外的空间?

我用C编写了简单的函数, void GetInput() { char buffer[8]; gets(buffer); puts(buffer); } 当我在gdb的反汇编程序中对它进行反汇编时,它会进行以下反汇编。 0x08048464 : push %ebp 0x08048465 : mov %esp,%ebp 0x08048467 : sub $0x10,%esp 0x0804846a : mov %gs:0x14,%eax 0x08048470 : mov %eax,-0x4(%ebp) 0x08048473 : xor %eax,%eax => 0x08048475 : lea -0xc(%ebp),%eax 0x08048478 : mov %eax,(%esp) 0x0804847b : call 0x8048360 0x08048480 : lea -0xc(%ebp),%eax 0x08048483 : mov %eax,(%esp) […]

编译器会优化静态函数的未使用参数吗?

我有一组函数都声明为static和fastcall 。 他们中的大多数都使用指向结构的指针,该结构在C ++中或多或少地扮演着this角色。 一些函数在结构中不需要任何东西,但为了统一起见,我还是要传递指针。 编译器是否会注意到该参数未被使用并且省略了为其分配寄存器?

在主要C / C ++编译器生成的代码中注册分配规则

我记得一段时间以前的一些规则(32位以前的英特尔处理器),当时很频繁(至少对我而言)必须分析C / C ++编译器生成的汇编输出(在我看来,当时是Borland / Turbo)找到性能瓶颈,并安全地将程序集例程与C / C ++代码混合。 比如将SI寄存器用于this指针,AX用于返回值,当汇编例程返回时应保留哪些寄存器等。 现在我想知道是否有更多流行的C / C ++编译器(Visual C ++,GCC,Intel ……)和处理器(Intel,ARM,…)的参考,如果没有,在哪里找到要创建的部分一。 想法?

宏定义中双重否定的目的是什么,如(!!(expr))?

可能重复: C ++代码中的双重否定。 我正在阅读代码库,并找到这样的东西: #define uassert(msgid, msg, expr) (void)((!!(expr))||(uasserted(msgid, msg), 0)) 我无法弄清楚为什么(!!(expr))而不是单个(expr) 。 无论如何,双重否定意味着积极,不是吗? 我错过了什么吗?

一元运算符“ – ”对C / C ++(以及不同的编译器)中的无符号数据类型做了什么?

例如: unsigned int numA = 66; // or anything really unsigned int numB = -numA; unsigned int numC = numA & numB 我知道可以使用按位补码运算符来获得二进制补码(与+1一起使用)。 我问的原因是因为我在国际象棋引擎的一些代码中偶然发现了这个问题。 国际象棋引擎做了许多“hacky”事情以获得绝对速度,特别是在每秒数百万次的移动生成function中。 (它是魔术位板移动生成的一个例子 – 它们中最优化的所有)并没有帮助。 这个国际象棋引擎代码特别只能在gcc编译下正常工作(我怀疑)。 不同的编译器如何对待这个? 特别是,与VS Studio 2012 Express中的C ++编译器相比,gcc如何处理这个问题。 谢谢。

在GCC预处理器输出中调试信息

我正在检查GCC生成的预处理输出,我在使用-save-temps标志生成的.i文件中看到了很多这些: # 8 “/usr/include/i386-linux-gnu/gnu/stubs.h” 2 3 4 stubs.h的绝对路径之前和之后的数字是什么意思? 它似乎是由预处理器插入的某种调试信息,并允许编译器发出引用此信息的错误消息。 这些行不会影响程序本身,但每个数字具体是什么?

在C / C ++中PHP的isset()的副部分

PHP有一个非常好的函数,isset($ variableName)。 它检查是否已在程序中定义$ variableName。 我们可以为C / C ++(某种符号表查找)构建类似的function吗?

LLVM – 使用clang自动运行自己的通行证

我为llvm写了一些自己的传递,以便与clang一起使用它们。 我将它们集成在llvm中(不是动态加载的)。 当我输入时,它们甚至列在Optimizations available:部分中: opt –help-hidden 当我打电话给clang时,我想自动运行我自己的一个通行证作为最后一个 : clang ./hello.bc -o ./hello 甚至用c代码: clang ./hello.c -o ./hello 当我手动使用opt运行传递时,会生成修改后的ByteCode并将其写入新的.bc文件: opt -my-pass ./hello_optimized.bc 当我用clang编译修改后的.bc时,会再次运行普通的clang优化,这会破坏我手动执行的传递的优化: clang -O0 -m32 ./hello_optimized.bc -o ./hello_optimized 我的问题是: 如何使用clang自动运行我自己的书面传递作为最后一次传递? 另一种可能的解决方案是完全停用所有通行证,或者至少取消clang / opt的死代码/function。 我怎么能这样做?

CPU /编程语言使用哪种取幂算法?

我一直在学习更快的取幂算法(k-ary,滑动门等),并想知道在CPU /编程语言中使用哪些算法? (我对这是否发生在CPU或编译器中都很模糊) 只是为了踢,这是最快的? 关于广度的编辑:它有意广泛,因为我知道有很多不同的技术可以做到这一点。 检查的答案有我想要的。

后增量运算符行为

可能重复: C,C ++,Java和C#中的前后增量运算符行为 这是一个测试用例: void foo(int i, int j) { printf(“%d %d”, i, j); } … test = 0; foo(test++, test); 我希望得到一个“0 1”输出,但我得到“0 0”什么给出?