美文网首页
PRE32-C. 不要在触发函数宏中使用预编译指令

PRE32-C. 不要在触发函数宏中使用预编译指令

作者: 大唐游子 | 来源:发表于2021-08-31 06:59 被阅读0次

PRE32-C. 不要在触发函数宏中使用预编译指令

宏的参数中不能包含预编译指令,比如 #define, #ifdef, 和#include. 根据C语言标准,6.10.3,第11段[ISO/IEC 9899:2011],这样做会引起 未定义的行为

The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.

同时参见 未定义行为 93.

这个规则同样适用于将预编译指令作为任何函数的参数,因为不知道函数是否是用宏实现。这包括所有的标准库函数,比如 memcpy(), printf(), 和assert(),因为不知道这些标准库函数是否用宏实现(C11, 7.1.4,第1段)。

不遵从规范的示例代码

在这个不遵从规范的示例代码中[GCC Bugs],编程人员使用了预处理指令来指定平台相关的参数。然而,如果memcpy()是通过宏来实现的,那么这个代码就会产生未定义行为。

#include <string.h>
  
void func(const char *src) {
  /* Validate the source string; calculate size */
  char *dest;
  /* malloc() destination string */
  memcpy(dest, src,
    #ifdef PLATFORM1
      12
    #else
      24
    #endif
  );
  /* ... */
}

遵从规范的解决方案

#include <string.h>
 
void func(const char *src) {
  /* Validate the source string; calculate size */
  char *dest;
  /* malloc() destination string */ 
  #ifdef PLATFORM1
    memcpy(dest, src, 12);
  #else
    memcpy(dest, src, 24);
  #endif
  /* ... */
}

风险评估

Rule Severity Likelihood Remediation Cost Priority Level
PRE32-C Low Unlikely Medium P2 L3

参考文献

[GCC Bugs] "Non-bugs"
[ISO/IEC 9899:2011] 6.10.3, "Macro Replacement"

相关文章

  • PRE32-C. 不要在触发函数宏中使用预编译指令

    PRE32-C. 不要在触发函数宏中使用预编译指令[https://wiki.sei.cmu.edu/conflu...

  • c++   inline

    在C中,编译器使用宏定义节省编译时间。在C++中使用内联函数来实现同样的效果。在程序编译时,编译器会将内联函数调用...

  • 【Unity Shader入门精要学习】Surface Shad

    Surface Shader的组成 一、编译指令 所谓编译指令就是使用命令来告诉Unity我将使用那些函数以及光...

  • C语言中预编译指令

    基本预编译指令#include 将指定头文件嵌入源文件中。#define 宏定义 条件预编译指令 (#ifdef...

  • define 与 typedef

    #define #define是宏定义,发生在预编译阶段,属于预编译指令,本身不参与编译,在编译预处理时进行简单的...

  • c高级自我学习(1)

    1 编译预处理和宏定 #undef指令删除前面定义的宏定义。 无参宏定义:宏名中没有参数。 1,宏定义中宏名用来表...

  • latex 报错合集

    参考文献中斜体未显示 使用 \emph{Convex Optimization} 编译后不显示斜体,要在宏包和正...

  • Swift3.0 基础语法

    Swift特色 苹果宣称Swift的特点是:快速、现代、安全、互动 Swift中取消了预编译指令包括宏 可以使用现...

  • 编译过程

    1、预编译(1)宏定义指令,如 #define a b(2)条件编译指令,如#ifdef,#ifndef,#el...

  • iOS源码分析:Block的本质

    新建一个命令行项目,代码如下: 使用编译指令编译成 cpp 文件查看源码: 得到的原始代码中 test 函数的源码...

网友评论

      本文标题:PRE32-C. 不要在触发函数宏中使用预编译指令

      本文链接:https://www.haomeiwen.com/subject/tobailtx.html