卓's profile成都,又是成都PhotosBlogListsMore ![]() | Help |
|
|
May 08 VS中的特殊指针值老记不住,做个备忘。
0xcdcdcdcd - Created but not initialised 0xdddddddd - Deleted 0xfeeefeee - Freed memory set by NT's heap manager 0xcccccccc - Uninitialized locals in VC6 when you compile w/ /GZ 0xabababab - Memory following a block allocated by LocalAlloc() February 17 令人困惑的inline,extern inline,staitc inline近日在一个头文件中使用inline来定义了一个需要高效率的函数,被告知在头文件中定义函数看起来不好,于是挪至C文件中重新定义,只在头文件中保留了声明。需要说明的是,该函数在其他几个文件中有使用,使用vc的编译器。
编译:通过!
链接:被告知有几个函数无法找到,这几个函数恰好就是我定义的inline函数
百思不得其解,于是询问旁人,被告知:这是microsoft编译器的问题,使用GCC则不会出现该问题。测试之,果然如此。又有建议称,在inline前面加extern可解决该问题,果然,编译链接通过。
问题解决了,不过这个问题实在让我困惑,究竟是什么原因造成这个问题呢?使用google深入调查了一番,找到一个有关inline的网页(http://www.greenend.org.uk/rjk/2003/03/inline.html)并结合其他资料,得出如下结论:
1. inline并不是在所有地方都会inline(这个是早就知道的,例如递归不能展开,使用了函数名作为地址也不能展开)
2. C标准对于何时该inline,何时不inline定义的很模糊,造成了不同编译器在实现inline功能时存在较大差异。
3. 如果在c文件中定义一个inline函数,那么编译器实际上一定会产生一份该函数的汇编代码(object code),该函数会在这个文件中任何一处调用中被展开(inline),并且整个程序中不能存在其他相同名字的函数。如果你想在别的文件中使用这个函数,那么可以将该函数的一个声明放到头文件中,但是,请注意:其他使用这个函数的文件中,该函数不被展开,而被作为一个普通的函数调用!!!
4. 如果inline 和extern 一起使用,则不会产生任何object code,其效果几乎和宏一样。那就意味着,这个函数的名字并没有进入符号表。
这会导致两个问题:第一,如果你使用该函数名作为一个指针,则会发生找不到符号的现象。第二,同样名字的函数,可以重复出现而编译器不会报错。
5. 如果inline 和static 一起使用,则是否产生object code将取决于这个函数如何使用。如果不存在对该函数地址的应用,且理论上是可以展开的,则不会生成object code。否则将产生object code,其影响从4可得知。
以上3-6的结论是GNU c的解释,c99标准中稍有不同
1. 声明和定义中都有inline,并且没有extern,则不会产生object code。它必须在同一个翻译单元(translate unit)中存在一个定义。如果你在另一个文件中定义了同名的函数,则编译器可以选择使用哪个函数,但是,编译器必须在文档中声明如何选择。
2. 某个函数的(任何)一个声明中有inline,但是其他的声明中没有inline或者extern,那么会产生object code。在同一个翻译单元(translate unit)中必须存在一个该函数的定义。那么其他翻译单元中对该函数的应用将作为一个普通的函数调用。
3. staitc inline 同时使用,则可能会也可能不会产生object code,这要看对该函数的使用情况而定。这点与GNU相同。
那么,为什么vc会报错就知道答案了,正是因为vc编译器遵循了C99的规则 1。 November 03 哪些排序算法是易于使用链表存储结构的?答案是:直接插入排序 直接选择排序 归并排序 基数排序
but why?
我认为是链表存储结构不适合做频繁的数据交换和查询操作,而上述几种排序应该都不需要这种操作。
待具体的验证!!!哪个知道确切答案说一声。
May 27 位域的一些解释MSDN上关于bit fileds的一些说明: struct-declarator : declarator The constant-expression specifies the width of the field in bits. The type-specifier for the declarator must be unsigned int, signed int, or int, and the constant-expression must be a nonnegative integer value. If the value is zero, the declaration has no declarator. Arrays of bit fields, pointers to bit fields, and functions returning bit fields are not allowed. The optional declarator names the bit field. Bit fields can only be declared as part of a structure. The address-of operator (&) cannot be applied to bit-field components. 位域所占的大小,与type-specifier declarator有关: 如下的定义 typedef struct { 其sizeof(bits)的值为12(32位vc环境) 但在gcc环境下,结果为4 而 typedef struct { sizeof(bits) == 1 这个是因为位域是type-specifier declarator声明的大小来分配实际存储区域。比如在gcc环境下,将任意一个char改为short,则结果为2,改为int,则结果为4。 我还没有搞清楚具体的细节。应该和编译器使用的对齐方式有关系,不同的编译器有不同的解释 内联函数中静态变量的定义问题内联函数中定义静态变量造成的后果? 视编译器如何处理inline关键字:
指针加减法的问题看看如下的代码: int *p1, *p2; int value;
p1 = (int *)0x500; p2 = (int *) 0x508; value = p2-p1; value的值是多少呢? 要时刻警惕,指针的加减法不等同于算术加减。 |
|
|