Tag: 编译器构造

c函数原型不匹配只是一个警告

请看下面的代码 #include void printOut() { static int i = 0; if (i < 10) { printOut(i); } } int main(int argc, char *argv[]) { return 0; } 我猜应该有一个错误,因为我调用了不存在的函数prototype.Actually,代码编译好mingw5编译器,这对我来说很奇怪,然后我改为Borland Compiler,我收到一条警告消息说没有printOutfunction原型,这只是一个警告吗? 更重要的是,代码执行良好,没有任何弹出错误窗口。

在C if-else语句中,是否应该首先出现更可能的条件?

我碰巧写了一个if-else语句,条件在大多数时候都是假的(检查是否分配了静态指针)。 哪一个对编译器进行优化会更好? 或者他们是平等的? 该函数将被调用很多次,因此优化其性能至关重要。 void foo() { static int * p = NULL; if (p == NULL) { p = (int *) malloc( SIZE * sizeof(int)); } //do something here } void foo() { static int * p = NULL; if (p != NULL) { //do something here } else { p = (int *) […]

为什么使用const不允许变量大小的对象初始化

这是错误的,因为可能无法初始化可变大小的对象 int size = 4; int array[size] = {1}; size是一个变量,但是编译器在创建array时不知道它的值(在编译时是不是为size指定了初始值为4?)? 在此之后让size发生变化,为什么会出现问题呢? 我的意思是,这些是连续的指令,在声明数组之前可能会改变size的值? 第二个问题:为什么不允许这样做: const int size = 4; int array[size] = {1}; 我宣称size为常量。 我知道const!=只读,并且将宏size声明为正确的方法。 但是,如果我保证使用const的编译器,我不会改变size的值,为什么不允许?

标准C库和系统调用如何协同工作?

我最近对编译器,标准库和内核的内部工作感兴趣。 当我在寻找标准C库的源代码时,我遇到了Glibc。 但它在Glibc的官方网站上所说的是: the library which defines the ”system calls” and other basic facilities such as open, malloc, printf, exit… 所以我猜Glibc实际上并没有提供标准C库的源代码,而是提供了对这些函数的系统调用,然后内核负责处理它们,对吗? 我想更多地了解这些事情。 例如,如何在C程序中执行sin , printf和strlen函数? 如果Glibc只提供系统调用,那些函数的实际源代码在哪里? 内核如何执行它们? 哪里可以找到执行这些function的内核部分的源代码?

printf / sprintf编译器警告是否有概念上的突破?

我注意到,当printf / sprintf函数的格式字符串中的转换说明符与相应参数的类型或计数不匹配时,大量C编译器会发出警告。 在我看来,这似乎是一个概念上的突破,因为根据语言规范,C没有内置函数。 所有编译器都应该知道printf / sprintf是他们的原型而不是他们的语义。 我知道printf / sprintf是标准的C函数,但是它们存在于一个单独的库libc中,你必须包含stdio.h才能导入它们的原型。 许多编译器所做的是分析格式字符串,该格式字符串也可以在运行时提供。 以上是否有意义?

#pragma optimize的代码有多便携?

使用#pragma optimize代码有多便携? 大多数编译器是否支持它以及对#pragma的支持有多完整?

__cdecl导致比__stdcall更大的可执行文件?

我找到了这个: 由于堆栈由被调用函数清理,因此__stdcall调用约定创建比__cdecl 更小的可执行文件,其中必须为每个函数调用生成堆栈清理的代码 。 假设我有两个function: void __cdecl func1(int x) { //do some stuff using x } void __stdcall func2(int x, int y) { //do some stuff using x, y } 在这里main() : int main() { func1(5); func2(5, 6); } IMO, main()负责清理对func1(5)的调用堆栈,而func2将清理func2(5,6)调用的堆栈,对吗? 四个问题: 1.为了调用main() func1 , main()负责清理堆栈,编译器在调用func之前和之后会插入一些代码(代码来清理堆栈)吗? 像这样: int main() { before_call_to_cdecl_func(); //compiler generated code for […]

什么是逃脱(\)角色背后的魔法

C / C ++编译器如何操作源代码中的转义字符[“\”]? 如何编写用于处理该字符的编译器语法? 编译器遇到该字符后会做什么?

我需要一个树转储选项,它在当前的gcc版本中不再存在

较旧版本的gcc(例如4.0.2或4.1.2)具有-df选项(请参阅http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Debugging-Options.html#index- fdump_002drtl_002dcfg-357 )。 我使用此选项转储文件filename.c.134r.life2和filename.c.126r.life1 ,因为我想从这些文件中提取一些值(例如每个方法的寄存器计数)。 问题是,在当前版本的gcc(例如4.2.2)中,此选项不再存在。 还有其他选项,名称为filename.c.135r.jump的树转储几乎相同。 但是这个转储中的寄存器计数也丢失了,我找不到具有该值的转储。 还有一个参数,它给了我当前gcc版本中的旧转储吗?

Objective-C如何编译?

我只是很好奇,Objective-C是否编译成C代码或者Objective-C运行时是否像程序上方的抽象层一样工作? 如果我不知道我在说什么,请提前抱歉!