Windows开发实录

饭是一口一口吃的...


预编译 Precompiler

Compiling C++ code is a long, slow process, especially compiling window API or other API library(boost).The Microsoft compiler can ameliorate this problem with a simple trick called precompiled headers. The trick is pretty slick: although every CPP file can potentially and legally give a sligthly different meaning to the chain of header files included on top of each Cpp file (by things like having different macros #define'd in advance of the includes, or by including the headers in different order), that is most often not the case. Most of the time, we have dozens or hundreds of included files, but they all are intended to have the same meaning for all the Cpp files being compiled in your application.

The trick consists on designating a special header file as the starting point of all compilation chains, the so called 'precompiled header' file, which is commonly a file named stdafx.h simply for historical reasons.

There are two steps to use precomplie in visual studio.

1. Create "stdafx.h" and "stdafx.cpp". Precompiler header" in project's properties to be "Create /Yc"Simply list all your big huge headers for your APIs in your stdafx.h file, in the appropriate order, and then start each of your CPP files at the very top with an #include "stdafx.h", before any meaningful content (just about the only thing allowed before is comments). In "stdafx.cpp", just include the "stdafx.h"  and nothing else.

2. Make sure that Including "stdafx.h" as the first line in all other source code (.cpp files). 

3. Change the "Precompiler header" in project's properties to be "Create /Yc". And then build the project in order to create projectname.pch file. So far, next time, when you compile your code, compiler will choose to retrieve obj file fromprojectname.pch other than recompile all the headers which are included in "stdafx.h".

4. Change the "Precompiler header" in project's properties to be "Use /Yu". 

Note: 

It's recommand to include the basic header such as header defined in STL, windows's basic api ("windows.h") or other third libraries (boost) in "stdafx.h".
If you met the compiler error: c1038 cannot open precompiled header file: 'debug\xxx.pch', please change the precompiler header to be "create/Yc". 

字符串拷贝的正确方法
字符串的拷贝不外乎使用 strcpy,strncpy 或者 memcpy方法,例如代码如下:
strcpy 
char *strcpy( char *strDestination, const char *strSource );

The strcpy function copies strSource, including the terminating null character, to the location specified by strDestination. No overflow checking is performed when strings are copied or appended. The behavior of strcpy is undefined if the source and destination strings overlap.

就是说当源字符串比目标字符串长度要少得时候使用是正确,同时能够以 null 结束。但是不提供溢出处理,正如如下代码所示,将会导致非定义异常。
#define BufLen 5
typedef char Buffer[BufLen];

char pp[] = {"helloworld"};
Buffer b1;
strcpy(b1, pp);
cout<<b1<<endl;
strncpy
char *strncpy( char *strDest, const char *strSource, size_t count );
当源长度少于或者等于目标长度,则只是拷贝源长度的所有字符,不包括null。但是当源长度大于目标长度,则会截取目标长度的内容,同时没有null结束,还是会导致overflow引起的非定义的影响。
memcpy
void *memcpy(
   void *dest,
   const void *src,
   size_t count 
);
唯一如果当长度过长时,拷贝指定的长度,同时不会引起非定义的行为(没有overflow产生),但是需要自己定义null如果长度过长,如果比目标长度短可以使用strlen(src)+1这样可以是null也拷贝。
建议使用方法为:
static const int BufLen = 127;
typedef struct _VAABuffer
{
	int len;
	char data[BufLen+1];
	_VAABuffer():len(0)
	{
		memset(data, 0, sizeof(data));
	}
	_VAABuffer(_VAABuffer& rhs)
	{
		memcpy(data, rhs.data, sizeof(data));
		len = rhs.len;
	}
	_VAABuffer(const char * src)
	{
		if (strlen(src) > BufLen)
		{
			memcpy(data, src, BufLen);
			data[BufLen] = '\0';
		}
		else
			strcpy(data, src);
		len = strlen(data);
	}
	_VAABuffer& operator=(_VAABuffer rhs)
	{
		memcpy(data, rhs.data, sizeof(data));
		len = rhs.len;
		return *this;
	}
	_VAABuffer& operator=(const char * src)
	{
		if (strlen(src) > BufLen)
		{
			memcpy(data, src, BufLen);
			data[BufLen] = '\0';
		}
		else
			strcpy(data, src);
		len = strlen(data);
		return *this;
	}
}VAABuffer;











原文地址:https://www.cnblogs.com/rogerroddick/p/2846711.html