Chinaunix首页 | 论坛 | 博客
  • 博客访问: 335580
  • 博文数量: 56
  • 博客积分: 2058
  • 博客等级: 中尉
  • 技术积分: 688
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-11 09:19
个人简介

code rush

文章分类

全部博文(56)

文章存档

2012年(2)

2011年(54)

分类: C/C++

2011-11-22 23:14:39

  1. C安全编码标准 笔记(1)
  2. 2011-11-22 23:11:28
  3. 1) 用内联函数或静态函数代替与函数相似的宏
  4.    因为宏是危险的,不小心就会传入一个带副作用的参数,比如i++. 这会引起未定义的行为。
  5.    因为语句替换,错误的绑定同名的局部变量和全局变量。
  6.    宏的交错执行在同一表达式中组合在一起,因为参数操作的顺序可能导致未定义的行为。
  7.    
  8.    例外:
  9.         用于实现局部函数的的宏无法用内联函数实现,即闭包的功能之一。
  10.         宏可以支持某种形式的惰性计算,内联函数无法实现该功能 例如 #define select(s,v1,v2)((s)?(v1):(v2)),根据选择结果,只计算v1,v2中的一个值。
  11.         宏可以用于产生编译时常量。
  12.         宏可以用于实现类型通用的函数,C++借助模板这样的机制实现。
  13.         宏参数具有按名称调用的语义,而函数则是按值调用。
  14.         
  15. 2)在宏参数名两边加上括号
  16.     保证语句正确展开,这个比较常见。
  17.     
  18.     例外:
  19.     当替换文本中的参数名由逗号分隔时,不管实际参数如何复制,因为逗号优先级低于其他任何操作符,不会导致意外替换。
  20.     使用##操作符连接变量,使用#把宏参数转换为一个新的标记。或者相邻的字符串常量,不能对宏参数加上括号。
  21.     
  22. 3)宏替换列表应该加上括号
  23.     用以保护表达式中所有优先级较低的函数
  24.     防止错误展开,导致出乎本意的行为
  25.     
  26.     例外:
  27.     如果一个宏展开为单个标识符或者函数调用,行为可控,不需要括号保护。

  28. 4)应该用typedef定义编码类型
  29.     typedef定义遵循作用域规则,且能正确定义指针类型,宏展开不遵循且不能正确体现指针定义。

  30. 5)不要复用标准头文件名
  31.     行为未定义.
  32.     
  33. 6)理解链接标记或者执行字符串化时的宏替换
  34.     预处理符##用于把两个标识符合并为一个标记符
  35.     当宏参数前面有个#是,预处理器就会用实际参数的文本来替代它,并转化为一个字符串常量
  36.     要注意宏展开的时机。什么时候发生的替换
  37.     
  38. 7)把头文件放在包含防护文件中
  39.     避免同一个同文件重复包含,导致变量定义重复。
  40.     
  41. 8)避免使用连续的问号
  42.     ??=     #
  43.     ??(        [
  44.     ??)     ]
  45.     ??/     \
  46.     ??<     {
  47.     ??>        }
  48.     ??'        ^
  49.     ??!        |
  50.     ??-     ~
  51.     当出现左面的三字符的时候,会被替换为右面的字符。为避免意外,慎用三字符。
  52.     
  53. 9)保证头文件名唯一

  54. 10)不用非安全函数代替安全函数
  55.     以防潜在缓冲区溢出
  56.     
  57. 11)在一个 do-while 循环中包装多条语句的宏
  58.     在内核文件中常见。用于把多条语句序列作为一个块执行。降低编译出错概率。
阅读(3445) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~