当前位置: 首页 > 编程日记 > 正文

Windows客户端C/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函数存在不安全隐患。为了提高程序的健壮性,需使用安全版函数替代。


比较常见的非安全函数:

wcsncpystrcpystrncpymemcpy
wmemcpysprintfwprintfvsnprintf

编译器报:

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 UNSAFEint _tmain(int argc, _TCHAR* argv[])
{int m = -1;char buffer[8] = {0};int n = -1;std::string str = "012345678901234567890123456789";
#ifdef UNSAFEmemcpy(buffer, str.c_str(), str.length()); 
#elsememcpy_s(buffer, _countof(buffer), str.c_str(), str.length()); 
#endifprintf("%d %d\n", m, n);return 0;
}
在release无优化的情况下,该段会产生脏数据并崩溃。(n的值已经被改变)


1.13 不要寄希望于inline声明

等级:【必须】

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

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

相关文章:

把自己朝九晚五的工作自动化了,有错吗?

作者 | Brian Merchant译者 | 谭开朗编辑 | 屠敏来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导读】用代码让自己工作开启自动化之际&#xff0c;是否意味着自己将面临被解雇的风险&#xff1f;2016年&#xff0c;Reddit上出现了一个匿名的帖子&#xff0c;内…

COM组件转换成.NET组件[转]

利用类型库导入器(Type Library Importer)可以将其包装成一个.NET组件&#xff0c;然后就可以像使用.NET组件一样使用它了。 .NET框架只是提供了一个包装&#xff0c;并没有真正改变原有的对象 1.找到要转换的.dll文件 2.在命令提示符窗口中输入.dll文件的文件路径&#xff0c;…

干货:Android 源码使用心得分享

我相信很多初学者会和我一样经常在网上去找Android开发源码&#xff0c;但是往往因为运行不起来非常的懊恼&#xff01;在做爱开发网站的时候&#xff0c;收集App代码时就遇到了这种困难&#xff0c;我相信网络上面的源码大部分在发布前都会人工测试&#xff0c;能够正常运行才…

60分钟入门深度学习工具PyTorch

「免费学习 60 节公开课&#xff1a;投票页面&#xff0c;点击讲师头像」作者 | Soumith Chintala中文翻译、注释制作 | 黄海广配置环境&#xff1a;PyTorch 1.3&#xff0c;python 3.7&#xff0c;主机&#xff1a;显卡&#xff1a;一块1080ti&#xff1b;内存&#xff1a;32g…

Windows客户端C/C++编程规范“建议”——指针

2 指针 2.1 尽量使用智能指针 等级&#xff1a; 【推荐】说明&#xff1a;正确使用智能指针可以省去指针管理的工作。2.2 类成员变量指针释放后一定要置空 等级&#xff1a; 【必须】说明&#xff1a;如果类成员变量指针在释放后没有置空&#xff0c;将出现如下问题&#xff1…

Bug tracker .net 部署经验(完善中)

Bug tracker .net 部署经验1. 软件要求windows 2003 serverSP1IISSQL sever 2005Net framework2. 安装和配置Bug tracker .net 提供了一个readme 文件。解压安装文件至某一个目录。在SQL SERVER 2005中新建一个数据库。确保IIS工作正常。定义一个虚拟目录&#xff0c;将其指向安…

Windows客户端C/C++编程规范“建议”——函数调用

3 函数调用 3.1 谨慎使用递归方法 等级&#xff1a; 【推荐】说明&#xff1a;递归方式控制不当&#xff0c;可能会导致栈空间不够而崩溃。一般的递归都可以使用循环代替。3.2 不要使用using namespace 等级&#xff1a; 【必须】说明&#xff1a;这是曾经教科书上的一种写法&a…

“一百万行Python代码对任何人都足够了”

作者 | Jake Edge译者 | Kolen出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;编程语言通常对其操作过程的各个方面都有或明或暗的限制。诸如标识符的最大长度或变量可以存储的值的范围之类的事情&#xff0c;这些是相当明显的例子&#xff0c;但是还有其他一些例子…

网吧电影客户端Realplayer的装配问题

网吧电影客户端Realplayer的装配问题 作者: 出处:网吧联盟 ( 20 ) 砖 ( 22 ) 好 评论 ( 1 ) 条 进入论坛 更新时间&#xff1a;2005-11-24 16:54关 键 词&#xff1a;网吧阅读提示&#xff1a;一般有过开网吧经验的朋友&#xff0c;应当知道如何让自己的realplayer播放器支…

基于Servlet+JDBC+Bootstrap+MySQL+AJAX权限管理系统项目实战教程

项目简介 权限系统一直以来是我们应用系统不可缺少的一个部分&#xff0c;若每个应用系统都重新对系统的权限进行设计&#xff0c;以满足不同系统用户的需求&#xff0c;将会浪费我们不少宝贵时间&#xff0c;所以花时间来设计一个相对通用的权限系统是很有意义的。 本系…

Windows客户端C/C++编程规范“建议”——表达式和运算

4 表达式和运算 4.1 比较操作中将常量设置为左值 等级&#xff1a; 【推荐】说明&#xff1a;编写代码时&#xff0c;如果将常量设置为右值。可能因马虎将“”写成“”导致逻辑错误。这种场景下&#xff0c;编译器是不会报错的&#xff0c;代码检查也比较容易被忽视。例子&…

GitHub标星1.5w+,从此我只用这款全能高速下载工具

「免费学习 60 节公开课&#xff1a;投票页面&#xff0c;点击讲师头像」作者 | Rocky0429来源 | Python空间&#xff08;ID:Devtogether &#xff09;大家好&#xff0c;我是 Rocky0429&#xff0c;一个喜欢在网上收集各种资源的蒟蒻...网上资源眼花缭乱&#xff0c;下载的方…

CSS text-transform 属性

定义 text-transform 对元素中的字母进行控制。 继承性&#xff1a;Yes 说明 这个属性会改变元素中的字母大小写&#xff0c;而不论源文档中文本的大小写。如果值为 capitalize&#xff0c;则要对某些字母大写&#xff0c;但是并没有明确定义如何确定哪些字母要大写&#xff0c…

SeaJS基本开发原则

SeaJS基本开发原则 在讨论SeaJS的具体使用前&#xff0c;先介绍一下SeaJS的模块化理念和开发原则。使用SeaJS开发JavaScript的基本原则就是&#xff1a;一切皆为模块。引入SeaJS后&#xff0c;编写JavaScript代码就变成了编写一个又一个模块&#xff0c;SeaJS中模块的概念有点类…

SMS主站点配置详细图解:Sms2003系列之二

SMS主站点配置在上一篇文章中&#xff0c;我们介绍了如何进行SMS2003&#xff0b;SP2的部署。本文中&#xff0c;我们将介绍如何进行SMS主站点的配置。在SMS中&#xff0c;站点(site)定义并包含了所有SMS管理的对象。当我们第一次安装SMS时&#xff0c;实际安装的是一个SMS站点…

2019,不可错过的NLP“高光时刻”

作者 | Elvis译者 | 凯隐、夕颜出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】对自然语音处理&#xff08;NLP&#xff09;领域而言&#xff0c;2019年是令人印象深刻的一年&#xff0c;本文将回顾2019年NLP和机器学习领域的重要事件。内容 主要集中于 NLP…

Windows客户端C/C++编程规范“建议”——结构

5 结构 5.1 不要使用goto 等级&#xff1a; 【必须】说明&#xff1a;在大型项目中&#xff0c;goto的滥用会导致灾难性后果。因为我们程序中一般不存在从一个函数体内部跳转到另一个函数体内部的场景&#xff0c;所以我们可以将跳转控制在函数内部&#xff0c;从而避免灾难。…

WinForm容器内控件批量效验是否允许为空?设置是否只读?设置是否可用等方法分享...

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/chinahuyong/article/details/47395633 WinForm容器内控件批量效验是否允许为空&#xff1f;设置是否只读&#xff1f;设置是否可用等方法分享 在WinForm程序中&#xff0c;我…

“不会Linux,怎么当程序员?”骨灰级程序员:干啥都不行。

说起优秀程序员的必备技能&#xff0c;我想大家都可以说很多&#xff0c;比如&#xff1a;数据结构、算法、数学、编程语言等等。但是&#xff0c;你可能会忽略了每一个程序员都应该掌握的技能&#xff1a;Linux。想一想&#xff0c;我们日常学习、求职、工作场景的中&#xff…

与空连接相关的几条命令

1)建立空连接:net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连接:net use \\IP\ipc$ "密码" /user:"用户名" (同样有3个空格)3)映射默认共享:net use z: \\IP\c$ "密码" /u…

Windows客户端C/C++编程规范“建议”——宏

6 宏 6.1 减少宏的使用 等级&#xff1a; 【建议】说明&#xff1a;宏的使用&#xff0c;将使得调试变得麻烦。所以在设计和使用宏的时候&#xff0c;请确保宏的逻辑是阅读者不会去关心细节的行为。6.2 宏定义中字母需大写 等级&#xff1a; 【必须】说明&#xff1a;为了醒目…

Struts2中通配符的使用

1、准备工作 新建一个JavaWeb项目HelloWord&#xff0c;导入Struts2的.jar包&#xff0c;在Web.xml下配置Struts2的监听&#xff0c;在src下添加Struts2的配置文件struts.xml&#xff1b;将该项目部署到服务器(Tomcat)上&#xff0c;运行检查项目是否部署成功和其他错误&#x…

关于Spark NLP学习,你需要掌握的LightPipeline(附代码)| CSDN博文精选

作者 | Veysel Kocaman, Data Scientist & ML Researcher ANKIT CHOUDHARY翻译 | 赵春光校对 | 申利彬来源 | 数据派THU(*点击阅读原文&#xff0c;查看作者更多精彩文章&#xff09;【导读】Pipeline具体来说是一个多阶段的序列&#xff0c;每个阶段由一个Transformer或者…

网络编程--ftp客户端的实现(c#版)

.net2.0对ftp有了一个很好的封装,但是确容易让人忽略ftp的真正内部实现,下面是我实现的ftp客户端的功能,其主要步骤是这样的:1、创建一个FtpWebRequest对象&#xff0c;指向ftp服务器的uri 2、设置ftp的执行方法&#xff08;上传&#xff0c;下载等&#xff09; 3、给FtpWebReq…

Windows客户端C/C++编程规范“建议”——文件

7 文件 7.1 正确使用#include 等级&#xff1a;【推荐】 说明&#xff1a;#include <>和#include “”导致编译器在搜索文件时&#xff0c;搜索的路径顺序不同。所以需要正确使用#include&#xff0c;以避免包含错了头文件。 语法形式操作带引号的形式预处理器按以下…

让你的网站支持 Emoji

SegmentFault有用户提出要支持Emoji表情输入&#xff0c;就研究了一下&#xff1a; 要记得备份数据库。 首先Mysql数据库在5.5.3之后开始支持utf8mb4字符集&#xff0c;所以mysql版本是5.5.3&#xff0b;的都可以设置让数据库存储Emoji表情&#xff0c;如果你的应用有移动端的&…

Windows客户端C/C++编程规范“建议”——变量和常量

8 变量和常量 8.1 尽量不要使用全局变量 等级&#xff1a; 【要求】说明&#xff1a;全局变量的滥用和goto的滥用一样&#xff0c;都是一种灾难。它将使得逻辑变得难以调试和控制。8.2 不涉及外部使用的全局变量需要使用static关键字修饰 等级&#xff1a; 【要求】说明&#…

机器学习模型五花八门不知道怎么选?这份指南告诉你

作者 | LAVANYA译者 | 陆离编辑 | 夕颜出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】在本文中&#xff0c;我们将探讨不同的机器学习模型&#xff0c;以及每个模型合理的使用场景。一般来说&#xff0c;基于树形结构的模型在Kaggle竞赛中是表现最好的&…

WinAPI: FlattenPath、WidenPath

不管什么曲线命令, 到来路径中都会变成 Bezier 线; 也就是说路径中只有直线和 Bezier 线.FlattenPath 和 WidenPath 都能够把路径中的 Bezier 线转换为近似的直线; 不同的是: 用 WidenPath 转换后貌似加宽了线, 其实它是转换成了一个包围路径的新路径(类似区域).本例效果图:代码…

Android - 小的特点 - 使用最新版本ShareSDK手册分享(分享自己定义的接口)

前太实用Share SDK很快分享&#xff0c;但官员demo快捷共享接口已被设置死&#xff0c;该公司的产品还设计了自己的份额接口&#xff0c;这需要我手动共享。 读了一堆公文&#xff0c;最终写出来&#xff0c;行&#xff0c;废话&#xff0c;进入主题。 之前没实用过ShareSDK分享…