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\n", m, n);
return 0;
}

在release无优化的情况下,该段会产生脏数据并崩溃。

(n的值已经被改变)


1.13 不要寄希望于inline声明

等级:【必须】

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

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

WindowsclientC/C++编程规范“建议”——函数的更多相关文章

  1. WindowsclientC/C++编程规范“建议”——前言

    前言 工作中接触了非常多编程规范.当中最有意思的是,公司近期公布了一版C/C++编程规范,然后我看到该规范的最后一段时,有这么一句:"该规范不适用于Windows平台开发".看来这 ...

  2. Python学习手册之 Python 之禅、Python 编程规范和函数参数

    在上一篇文章中,我们介绍了 Python 的正则表达式使用示例,现在我们介绍 Python 之禅. Python 编程规范和函数参数.查看上一篇文章请点击:https://www.cnblogs.co ...

  3. Windows客户端C/C++编程规范“建议”——风格

    本文来自:http://blog.csdn.net/breaksoftware/article/details/37935459 命名风格也非常适用于C# 9 风格 9.1 优先使用匈牙利命名法 等级 ...

  4. 51单片机C语言学习笔记8:单片机C51编程规范

    1.单片机C51编程规范- 前言  为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范. 2.单片机C51编程规范-范围 本标准规定了程序设计人员进行程序设计时必须遵循的规范.本 ...

  5. C语言编程规范

    C语言编程规范 6 函数与过程 6.1 函数的功能与规模设计 函数应当短而精美,而且只做一件事.不要设计多用途面面俱到的函数,多功能集于一身的函数,很可能使函数的理解.测试.维护等变得困难. 6.2 ...

  6. Batsing的网页编程规范(HTML/CSS/JS/PHP)

    特别注意!!!我这里的前端编程规范不苟同于Bootstrap的前端规范. 因为我和它的目的不同,Bootstrap规范是极简主义,甚至有些没有考虑到兼容性的问题. 我的规范是自己从编程实践中总结出来的 ...

  7. JAVA 编程规范(上)

    2016-03-20 J120-CHARLIEPAN JAVA 编程规范(上) 1.      应用范围 本规范应用于采用J2EE规范的项目中,所有项目中的JAVA代码(含JSP,SERVLET,JA ...

  8. Python编程规范(PEP8)

    Python编程规范(PEP8) 代码布局 缩进 对于每一次缩进使用4个空格.使用括号.中括号.大括号进行垂直对齐,或者缩进对齐. 制表符还是空格? 永远不要将制表符与空格混合使用.Python最常用 ...

  9. Python 编程规范-----转载

    Python编程规范及性能优化 Ptyhon编程规范 编码 所有的 Python 脚本文件都应在文件头标上 # -*- coding:utf-8 -*- .设置编辑器,默认保存为 utf-8 格式. ...

随机推荐

  1. UILabel垂直方向显示(上下的顺序显示)。

    NSString* text = @"一"; NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFont ...

  2. 【转载】cocos2dx 中 Android NDK 加载动态库的问题

     原文地址:http://blog.csdn.net/sozell/article/details/10551309 cocos2dx 中 Android NDK 加载动态库的问题 闲聊 最近在接入各 ...

  3. Windows 环境下 Docker 使用及配置

    原文引用: https://www.cnblogs.com/moashen/p/8067612.html 我们可以使用以下两种方式在Windows环境下使用docker: 1. 直接安装: Docke ...

  4. poj3009 Curling 2.0 深搜

    PS:以前看到题目这么长就没写下去了.今天做了半天,没做出来.准备看题解,打开了网站都忍住了,最后还是靠自己做出来的.算是一点进步吧. 分析: 题目的意思没明白或者理解有偏差都没办法做题.看样例3和样 ...

  5. Android App 开机启动画面和开机自动启动APP程序设置

    1.当前比较成熟一点的应用基本上都会在进入应用之显示一个启动界面 如腾讯微博 2.准备元素  需要开机启动的图片一张 3.新建Activity AlphaAnimation动画:控制对象alpha水平 ...

  6. 如何安全使用dispatch_sync

    概述 iOS开发者在与线程打交道的方式中,使用最多的应该就是GCD框架了,没有之一.GCD将繁琐的线程抽象为了一个个队列,让开发者极易理解和使用.但其实队列的底层,依然是利用线程实现的,同样会有死锁的 ...

  7. AdminLTE框架基础布局使用

    boxbox-solid:去掉顶部边框线box-headerwith-border:添加头底部边框线 按钮:—— btn btn-default 默认<div class="btn-g ...

  8. Scala语言学习笔记——方法、函数及异常

    1.Scala 方法及函数区别 ① Scala 有方法与函数,二者在语义上的区别很小.Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量.换句话来说在类中定义的函数即是方法 ② Scal ...

  9. BZOJ : [Usaco2013 Nov]Crowded 单调队列

    正反两遍个来一次单调队列 DP 即可. Code: #include<cstdio> #include<deque> #include<algorithm> usi ...

  10. 分享接口管理平台 eoLinker AMS 线上专业版V3.0,只为更好的体验,了解一下?

    不知不觉中,eoLinker AMS从2016年上线至今已经三个年头,按照一年一个大版本的迭代计划,我们终于迎来了eoLinker AMS 专业版3.0. AMS产品也从最初专注于API文档管理,成长 ...