zoukankan      html  css  js  c++  java
  • WindowsclientC/C++编程规范“建议”——函数

    1 函数

    1.1 代码行数控制在80行及以内

    等级:【要求】
    说明:每一个函数的代码行数控制应该控制在80行以内。假设超过这个限制函数内部逻辑一般能够拆分。假设试图超过这个标准。请列出理由。

    但理由不包括例如以下:

    • 无法拆分。

    • 流程内部逻辑复杂。无需拆分,即使拆分了。拆分的函数也不会被其它地方用到。(解释:拆分能够降低代码行数,提炼后的函数能够方便读者高速理解函数逻辑并定位问题。)

    1.2 代码列数控制在100字符及以内

    等级:【要求】
    说明:每行代码不能够超过100字符。假设超过这个字符数,代码的美观度和可阅读性将减少。

            样例: 快哭了

    for ( std::vector<ATL::CString, COneClass>::iterator it = m_VecObjects.begin(); it != m_VecObjects.end(); it++ ) 

            这一行一共113列。
            我们能够这么改动:微笑

    typedef std::vector<ATL::CString, COneClass>::iterator VecCStClsIter;
    for ( VecCStClsIter it = m_VecObjects.begin(); it != m_VecObjects.end(); it++ )

            或者使用boost/C++11中的auto:微笑

    for ( auto it = m_VecObjects.begin(); it != m_VecObjects.end(); it++ )


    1.3 避免反复代码

    等级:【要求】
    说明:假设逻辑中反复代码行数超过30行,应该考虑将该逻辑提炼成一个函数。这样既能够增强代码可读性。还能够减少未来代码维护的代价。


    1.4 函数名称不能够全大写

    等级:【必须】

    说明:在“1.6宏”规则中,我们已经规定宏要使用全大写方式定义。所以为了区分宏和函数,函数名不能够使用全大写。


    1.5 当函数不须要返回值时不要为其设计返回值

    等级:【要求】

    说明:假设给不须要返回值的函数设计返回值。将为使用该函数的人带来困惑。


    1.6 对于有返回值的函数要求每一个退出分支都要有显示的返回值

    等级:【必须】

    说明:对于有返回值的函数。假设逻辑进入一个没有返回值的分支。将导致未知错误。


    1.7 大内存数据參数须要使用引用传递

    等级:【要求】

    说明:假设不使用引用传递,则在函数调用时产生内存拷贝行为。

    大幅减少函数运行效率。


    1.8 不会被改变的引用传递入參使用const声明

    等级:【要求】

    说明:避免函数中对入參改动导致逻辑出错。


    1.9 入參先于出參排列

    等级:【要求】

    说明:这样安排一般复合理解的须要。

    实际上非常多Windows API也是基于这种规则设计的。


    1.10 默认參数在函数定义时(非声明)使用凝视标记默认值

    等级:【推荐】
    说明:这样将在声明定义分离的模式下,阅读者能够高速知道该函数存在默认參数的情况。

    void print( int nValue = 1 );
    .......
    void print( int nValue /*= 1*/ ) {
    	printf("%d", nValue); 
    } 


    1.11 慎重使用须要64位变量函数

    等级:【要求】
    说明:系统中非常多须要64位变量的API存在于vista以上的系统中。

    假设我们代码中使用该类函数,将导致在XP系统上执行出错(当然能够动态载入系统dll并寻址以解决该问题)。


    1.12 禁止使用非安全函数

    等级:【必须】

    说明:曾经一批老的C函数存在不安全隐患。

    为了提高程序的健壮性。需使用安全版函数替代。 


            比較常见的非安全函数:

    wcsncpy strcpy strncpy memcpy
    wmemcpy sprintf wprintf vsnprintf

            编译器报:

    warning C4996: 'XXXX': This function or variable may be unsafe. Consider using wcsncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.


            解决方式:
            假设是由于我们使用strsafe.h导致VC库或者可信的第三方库(比方boost)报该warning。则我们能够调整strsafe.h的包括位置等方法去除。
            其它场景出现该warning,应该使用安全函数替代。这些函数的安全版本号通常是在原函数后面添加_s。

    并新增一个空间大小的參数。

            使用这些不安全函数存在下面危害:

    1. 产生脏数据。

      我们可能声明一个变量为1,可是经过运行后,在没有运行改动该变量的情况下,可能数据已经变成一个我们无法估计的值了。见下例n的输出。

    2. 进入错误逻辑。

      由于栈空间被破坏,我们的逻辑可能进入并不是我们希望进入的函数内部运行。

    3. 导致崩溃。

      由于溢出会导致堆栈被破坏。所以极可能导致程序崩溃。由于我们栈被破坏,导致栈回溯产生错误,将严重影响我们dump的分析。

    4. 被攻击。缓冲区溢出攻击,这样的攻击方式已经非常古老了。非常多漏洞都是这样的错误导致的。

            简单的样例:委屈

    #define UNSAFE
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int m = -1;
    	char buffer[8] = {0};
    	int n = -1;
    	std::string str = "012345678901234567890123456789";
    #ifdef UNSAFE
    	memcpy(buffer, str.c_str(), str.length()); 
    #else
    	memcpy_s(buffer, _countof(buffer), str.c_str(), str.length()); 
    #endif
    	printf("%d %d
    ", m, n);
    	return 0;
    }
            在release无优化的情况下,该段会产生脏数据并崩溃。

    (n的值已经被改变)


    1.13 不要寄希望于inline声明

    等级:【必须】

    说明:VS平台上一个被声明为inline的函数并不一定会被内嵌到代码中,而是和普通函数一样。由于VS会根据自己的规则推断是否须要做真实的“内联”。

    (转载请指明出于breaksoftware的csdn博客)

  • 相关阅读:
    Java io流 之file类(文件和文件夹)
    异常处理
    封装
    面向对象与类
    包与模块的使用
    模块
    递归函数
    迭代器
    装饰器
    函数基础2
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6892365.html
Copyright © 2011-2022 走看看