一次使用#pragma有什么危险

What are the dangers of using #pragma once?

本文关键字:#pragma 什么 危险 一次      更新时间:2023-10-16

现代C和C 编译器支持非标准#pragma once,预处理器指令,其目的与经典标题卫队相似:

#ifndef hopefully_unique_identifier_that_doesnt_hurt_the_code
#define hopefully_unique_identifier_that_doesnt_hurt_the_code
  // some code here
#endif

一个问题,我知道,经典方法是,一旦包含了标头,就必须 #undef再次将其包括在内(对我来说,是一个主要的代码 - 闻起来,但这在这里的意义旁边)。#pragma once方法出现同样的问题,但没有允许将标头包含在内的可能性不止一次。

经典诉求的另一个问题是,您可能会意外地在无关的地方定义相同的宏,因此我无法想象的不包括标题或做其他讨厌的事情。通过保持某些约定(例如将宏基于UUID般的对象(即随机字符串)或(较不太最佳的方法)),在实践中,这在实践中很容易避免。。

我很少在现实生活中经历任何这些潜在问题,所以我并不认为它们是主要问题。

我对#pragma once可以想到的唯一潜在的现实生活中的问题是,这不是标准的事情 - 您依靠到处都不可用的东西,即使存在,实际上,实际上,*)。

那么,除了我已经提到的问题外,#pragma once存在哪些潜在问题?在实践中,我对拥有它的可用性有太多信心吗?

(*)一些只有少数人使用的次要编译器,不包括。

我遇到的一个问题是使用#pragma once是在包含位于多个位置的相同文件时。使用#pragma once,它被认为不同,而不是#ifndef/#define Guard。

我已经与一组不错的编译器合作:

  • GCC
  • clang/llvm
  • IBM XLC
  • 英特尔C 编译器

唯一不支持#pragma once的编译器是IBM XLC编译器,它甚至不支持C 11,因此我不感兴趣。如果您需要在蓝色基因/Q上使用IBM XLC编译器,则不能使用#pragma once

很久以前,某些编译器不了解包含的后卫习语,并且会反复打开标题文件,只是发现预处理器将内容减少到一无所有。使用这些编译器,使用#pragma once将带来编译时间的好处。但是,这已经在主要编译器中实施,因此这没有什么区别。

也许您有一些嵌入式系统的特殊编译器。那可能无法使用#pragma once

一般而言,我更喜欢#pragma once,因为当您复制标头文件以通过重复或扩展类进行增量进行重构时,您不能忘记更改Include include Guard Macro的名称。

因此,除某些编译器外,我不知道您对#pragma once有任何困难问题。

在使用#pragma once时,您正在放弃便携性。您不再编写C或C ,而是作为编译器扩展程序允许的。

可能会导致您头痛,如果您的代码曾经针对其他平台。

出于这个原因,我从不使用它。

鉴于文件的名称和位置是唯一的,我将其用作我的guard。此外

#if !defined(foo)
#define foo 1
/*code*/
#endif

自1996年以来我遇到的每个平台都可以使用。