程序员的自我修养: 程序运行的基石 C/C++运行库
一个C语言运行库大致包含了如下功能:
1. 启动与退出: 包括入口函数及入口函数所依赖的其它函数等
2. 标准函数: 由C语言标准规定的C语言标准库所拥有的函数实现.
3. I/O: IO功能的封装和实现
4. 堆:堆的封装和实现
5. 语言实现: 语言中一些特殊功能的实现.
6. 调试: 实现调试功能的代码.
在这些运行库的组成成分中, C语言标准占据了主要并且大有来头.
1. 变长参数
函数的实现如下:
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
//va_start取第一个参数的地址, 并在栈上向上移动指针
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
//va_arg主要是先移动指针,再取上一个值.
//注意: t是指要传入的类型,应为要确定移动的指针的远近.
#define _crt_va_end(ap) ( ap = (va_list)0 )
//使ap指针为0
//主要是利用栈的原理.
#include <stdio.h>
#include <stdarg.h>
int sum(int a, ...)
{
int v = 0;
va_list ap;
va_start(ap, a);
while(a--)
v += va_arg(ap, int);
va_end(ap);
return v;
}
int main()
{
printf("%d", sum(9, 1,2,3,4,5,6,7,8,9));
return 0;
}
2. 非局部跳转
#include <setjmp.h>
jmp_buf b;
void f()
{
longjmp(b, 1);
}
int main()
{
if(setjmp(b))
printf("World!");
else
{
printf("Hello ");
f();
}
return 0;
}
结果: Hello World!
当调用longjmp时,运行到setjmp返回的位置,并把setjmp的返回设置为1
关于不同版本CRT的问题
1. 为什么用VC2008编译的程序无法在别人的机器上运行?
因为VC2008编译的程序使用了manifest机制, 这些程序必须依赖于相对应版本的运行库.
一个解决办法就是使用静态链接, 这样就不需要依赖于CRT的DLL.
另一办法是将相应版本的运行库与程序一起发布给最终用户.
2. 如果一个程序里面的不同obj文件或dll文件使用了不同的CRT, 会不会有问题?
如果只有obj没有dll, 这时是静态链接, 不同的obj在编译时用到了不同版本的静态CRT. 一般是不会出现问题的. 因为目标文件对静态库引用只是在目标文件的符号表中保留一个记号, 不进行链接, 没有静态库的版本信息.
但是如果含有不同版本的dll文件, 则有可能出现问题.
相关文档:
C++不定参数的用法 (C类似)
2009-11-19 15:41
/*
va_list vl; //定义一个指向参数列表的变量(一个...指针)
va_start(vl,first_param); //把指向参数列表的变量初始化
va_arg(vl,mode); //获取下一个参数,参数类型由第二个参数指定,第二个参数用于在va_arg内部进行尺寸计算,以便找到下一个参数
va_end(vl); //结束
......
C/C++是最主要的编程语言。这里列出了50名优秀网站和网页清单,这些网站提供c/c++源代码。这份清单提供了源代码的链接以及它们的小说明。我已尽力包括最佳的C/C++源代码的网站。这不是一个完整的清单,您有建议可以联系我,我将欢迎您的建议,以进一步加强这方面的清单。
1、http://snippets.dzone.com/tag/c/ --数以千计 ......
http://www.trendcaller.com/2009/05/hadoop-should-target-cllvm-not-java.html
Sunday, May 10, 2009
Hadoop should target C++/LLVM, not Java (because of watts)
< type="text/javascript">
digg_url="http://www.trendcaller.com/2009/05/hadoop-should-target-cllvm-not-java.html";
Over the years, ......
今天在VS2005调试一个C# C/S程序,当通过RFC与SAP连接时间过长时,出现此错误,在网上找到解决办法。
VS2008上的一个程序,通过Oracle.DataAccess.dll执行drop user
cascade操作,我在sqlplus执行此操作大约需要一分钟左右时间,当我在VS2008中debug启动此程序时,一直接收到
“ContextSwitchDeadlock is detected& ......