Apr
error C2653: ‘std’ : is not a class or namespace name
by huubby in C and CPP
Today, when I created a Win32 Console Application in VS2005, and wrote the code as follow:
#include “stdafx.h”
int _tmain(int argc, _TCHAR* argv[])
{
std::string str = “”;
str += “helllo”;
str += “world”;
printf(“%s”, str);
return 0;
}
I got compile errors:
error C2653: ‘std’ : is not a class or namespace name
…
At the beginning, I thought it caused by a static library on which my new project depended. Then, I removed the static library dependent, but it didn’t work.
As you know, googling is a final solution when you find something you cann’t solve. I google it and figure it out. It’s simple, as MS has a bug in this situation.
You can find why this happend here, a relational situation about the issue is here.
Over!
Mar
restrict关键字
看代码看到个restrict,头一次知道还有这么个关键字,在维基查到基本用法和解释。本着好记性不如烂笔头的原则,翻译这篇维基贴在这里。
在C语言的一个标准(C99)里,有一个用于修饰指针声明的关键字-restrict,它是程序员给编译器的一个意向声明,表明只有此指针或者基于此指针的某个值(比如 pointer+1)可以访问其指向的对象。这个关键字限制了指针别名(译注:即指向同一对象的不同指针),目的在于进行编译器优化。如果这个程序员没有遵守这个意向声明,并且这个对象由一个独立指针访问到的话,会造成未定义的行为。( 译注:我也没搞懂这一大段话什么意思 ^_^ 不过看下面的例子应该差不多能理解这个关键字的用法)
如果知道只有一个指针指向某个内存块的话,编译器就能进行优化,以生成更高效的代码。下面这个例子能清楚解释这一点。
void updatePtrs(size_t *ptrA, size_t *ptrB, size_t *val)
{
*ptrA += *val;
*ptrB += *val;
}
这段代码里面,指针ptrA , ptrB, val可能指向同一块内存,所以编译器不能对代码进行优化。
load R1 ← *val ; 加载val指针的 load R2 ← *ptrA ; 加载ptrA指针的值</pre> add R2 += R1 ; 相加 set R2 → *ptrA ; 更新ptrA指针的值 ; 对ptrB指针的操作类似,注意,这里val指针被加载两次,因为ptrA有可能和val指向同一块内存 load R1 ← *val load R2 ← *ptrB add R2 += R1 set R2 → *ptrB
如果使用restrict关键字,函数声明为:
void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val);
编译器就能知道ptrA, ptrB, val三个指针指向不同的内存块,更新其中一个不会影响到其他的,从而对代码进行优化。当然,这里要由程序员保证这三个指针不指向同一块内存。
load R1 ← *val load R2 ← *ptrA add R2 += R1 set R2 → *ptrA ;编译器知道指针val的值没有改变,所以没有重新加载它,优化了汇编代码 load R2 ← *ptrB add R2 += R1 set R2 → *ptrB
还有一个例子是memcpy函数,memcpy(void*, void*, nbytes)的前两个指针参数被声明为restrict,告诉编译器两个数据块没有重叠,便于进行优化,使得memcpy的速度更快。如果程序员用相同的指针作为这两个参数的值,那么memcpy函数会产生未定义的行为。
(译注:memcpy的前两个参数确实声明为restrict,但是用相同的指针做参数传进去测试,没发现异常行为,此处存疑。)
另:推荐一个专栏,M. Tim Jones 专栏,Linux 内核、虚拟化及其他技术深层剖析。(你可以在这个专栏中看到restrict的身影)
Mar
Mar
linux编译生成动态库
工作交接,手头没事闲的慌,试了一下怎么在Linux下生成动态库。放狗一搜,铺天盖地的文章讲这个(PS:这年头,好像所有的东西都有人介绍过)。随便点了篇照着试了一下,很容易就搞定。只是有一件事不太爽,最后一步测试的时候,我发现找不到生成的那个动态库,然后又觉得这个场景似曾相识。在记忆里google了一下,发现原来N天之前我已经试验过了,结果现在又全还给google。为避免下次继续出现这种情况,还是把自己的实验过程写出来,免得再还回去。
实验开始,先准备一个要封成动态库的类。
头文件:
//myclass.h
class CMyClass
{
public:
int add(int x, int y);
};
实现:
//myclass.cpp
#include "myclass.h"
int CMyClass::add(int x, int y)
{
return x + y;
}
//main.cpp
#include "myclass.h"
#include <iostream>
using namespace std;
int main(void)
{
CMyClass mycls;
cout<<"10 plus 3 is "<<mycls.add(10,3)<<endl;
}

