CodeQL 文档

重复包含守卫

ID: cpp/duplicate-include-guard
Kind: problem
Security severity: 
Severity: error
Precision: high
Tags:
   - reliability
   - maintainability
   - modularity
Query suites:
   - cpp-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

头文件中常见的模式是使用预处理指令来防止头文件在每个翻译单元中被处理多次。这种做法旨在防止编译错误。但是,预处理器包含守卫本身也容易出现人为错误,因为每个包含守卫都必须分配一个唯一的宏名称才能正常工作。如果两个头文件使用相同的守卫宏,编译器可能会意外地跳过它遇到的第二个文件,从而导致编译错误或配置错误。

该查询将标记任何包含守卫开头处的预处理器 #ifndef 指令,只要该包含守卫与项目中的另一个包含守卫匹配。浏览结果列表,您将能够找到使用相同宏的其他指令。

建议

首先确定重复的包含守卫是否危险。重复的包含守卫可能会导致头文件在不应该被跳过时被跳过,但有时这种设计是故意使用的,目的是‘覆盖’现有的头文件。

要解决此问题,请重命名除一个之外的所有重复包含守卫使用的宏。请记住,要更改 #ifndef#define 指令以使用新的宏名称。或者,考虑使用 #pragma once 指令来防止多次包含,而无需定义唯一的宏。

示例

以下是一些示例,其中两个头文件意外地被赋予了相同的包含守卫宏。要解决此问题,请重命名第二个文件中宏的所有出现,例如,将其重命名为 ANOTHER_HEADER_FILE_H。

// header_file.h

#ifndef HEADER_FILE_H
#define HEADER_FILE_H

	// ...

#endif // HEADER_FILE_H
// another_header_file.h

#ifndef HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H
#define HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H

	// ...

#endif // HEADER_FILE_H

参考文献

  • ©GitHub, Inc.
  • 条款
  • 隐私