转载:
http://c.chinaitlab.com/cc/basic/200805/748036.html
为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
方式一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
方式二:
#pragma once
... ... // 一些声明语句
#ifndef 的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。
#pragma once 则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。
#pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受语言天生的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,换言之,它的兼容性不够好。也许,再过几年等旧的编译器死绝了,这就不是什么问题了。
我还看到一种用法是把两者放在一起的:
#pragma once
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。
选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。事实上,只要有一个合理的约定来避开缺点,我认为哪种方式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员来搞定。
btw:我看到GNU的一些讨论似乎是打算在GCC 3.4(及其以后?)的版本取消对#pragma once的支持。不过我手上GCC 3.4.2和 GCC 4.1.1仍然支持#pragma once,甚至没有deprecation warning。VC6及其以后版本亦提供对 #pragma once方式的支持。我想这一特性已经稳定下来了。
分享到:
相关推荐
在VC++环境下,我们可以通过多种方式实现这个功能,防止程序同时启动多次。以下是一些常用的方法: ### 1. 使用Mutex(互斥体) Mutex是一种同步对象,用于控制对共享资源的访问。在程序启动时创建一个全局命名的...
如果已经包含过,则不会再次包含,这有助于避免重复加载同一文件导致的问题。例如,你可能有多个文件都包含了同一个配置文件,使用`include_once`可以防止配置被多次读取和解析。 - `require_once`:同样,`require...
`_once`版本的函数则会在多次调用同一文件时仅执行一次,避免重复包含。 本地文件包含漏洞的利用常常涉及读取服务器上的敏感文件,如系统配置、数据库信息等。攻击者可能会尝试通过构造URL或表单参数来包含这些敏感...
例如,当你有一个包含类定义的文件,且该文件可能被多个其他文件包含时,使用`require_once`可以防止类被多次定义,从而避免潜在的冲突和错误。 请注意,`require_once`的“once”关键字并不是指文件在整个PHP进程...
这有助于避免因多次包含导致的变量覆盖或函数重定义问题。 4. `require_once()` 函数: - 语法:`require_once('/path/to/filename')` - `require_once`与`require`类似,但在尝试包含文件之前会检查该文件是否...
不过,使用_once语句会增加系统的一个判断过程,这个判断过程会消耗一些性能,因此,如果能够通过合理组织代码和目录结构来避免包含同一文件多次,那是更为理想的。 在路径的问题上,include与require允许使用相对...
每个成员可以独立负责一部分功能模块,通过各自独立的文件进行编码,然后整合到一起,避免了多人同时编辑同一文件的冲突问题。 **操作步骤** 1. **任务实例**:例如,要使用LCD1602字符液晶显示时间,首先需要准备...
- **`include_once`** 和 **`require_once`**: 这两个函数与`include`和`require`类似,但具有检查机制,可以避免同一文件被多次包含。 - **区别**: - **`include_once`**: 在文件首次包含时执行,之后的包含请求会...
这在编写大型项目或使用第三方库时特别有用,可以防止因多次导入同一文件而导致的问题。 3. `require`语句: `require`与`include`功能基本相同,都是用来导入文件。但是,当`require`尝试导入的文件不存在或者解析...
在头文件的管理中,避免多次包含同一文件通常通过#ifndef...#define...#endif结构来实现。 头文件的包含有两种形式,尖括号`< >`用于系统库,双引号`" "`用于用户自定义的头文件。例如,`#include <msp430f6638.h>`...
在C和C++编程中,头文件的包含是构建程序不可或缺的一部分,它们允许代码复用和模块化。...同时,为了避免头文件被多次包含,通常会使用`#ifndef`、`#define`和`#endif`来实现头文件的保护,防止重复定义问题。
- 当需要在多个文件中可能独立引入同一份代码,但又不希望多次执行时,应使用`include_once`。 在实际项目中,合理使用这些函数可以优化代码结构,提高代码的可维护性和效率。例如,常将版权信息、通用函数库、...
同时,为了避免头文件被多次包含导致的错误,通常会使用`#ifndef`、`#define`和`#endif`来创建头文件保护,确保头文件只被包含一次。 例如,在`func1.h`中可能有如下代码防止重复包含: ```c #ifndef FUNC1_H #...
在例子中,将`require`改为`include`后,虽然同样出现警告,但程序会继续执行,多次尝试包含文件并显示相同的错误信息,直到循环结束。 此外,还有一个相关的`require_once`函数,它的作用是确保目标文件只被包含一...
- **避免多次重定向**:不要在同一程序中多次对同一标准流进行重定向,除非有明确的需求。重复重定向可能会导致不可预料的行为。 - **资源管理**:使用完毕后,记得关闭文件,释放资源。虽然在程序结束时系统会自动...
如果在同一段代码中多次包含同一文件,可能会导致函数、变量的重复定义,从而造成程序错误。为了解决这个问题,PHP 提供了`require_once()`和`include_once()`函数。这两个函数会检查指定的文件是否已经被包含过,...
这是防止重复包含同一文件和避免潜在冲突的好方法。例如,如果你有一个配置文件包含在多个文件中,使用 `require_once()` 或 `include_once()` 可以确保配置文件只被加载一次。 总结: - `require()` 和 `include...
检查所有被包含的H文件,确保没有多次包含同一文件或多个文件之间存在相互包含导致的循环引用。 3. 符号冲突:在不同库或自定义H文件中,可能存在同名但功能不同的符号。为了避免冲突,可以使用`#ifndef`、`#define...
这种形式的库文件使得多个程序可以共享同一份内存映像,节省了磁盘空间和内存资源。 描述中提到,这个版本的OpenCV是已经为CentOS 64位系统编译好的,这意味着它已经过了一次完整的构建过程,包括配置、编译、链接...