内外兼备警卫之间的语用差异? [英] Difference between pragma once inside and outside include guards?

查看:104
本文介绍了内外兼备警卫之间的语用差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#pragma once放置在包含防护中而不是外面时是否有区别?

情况1:

#ifndef SOME_HEADER_H
#define SOME_HEADER_H
#pragma once

情况2:

#pragma once
#ifndef SOME_HEADER_H
#define SOME_HEADER_H

出于好奇,我只是想知道是否有某些特殊情况下我应该优先选择一个或另一个(情况1或情况2),因为我决定在我的代码中将两者(编译指示符和标头保护符)组合在一起./p>

我认为你们是在误解我的问题...我是在问pragma once的位置,而不是一次-vs-标头卫兵的注目.

解决方案

有一个微妙的区别,如果在包含头之前已经定义了SOME_HEADER_H,则在第二种情况下,预处理器将处理#pragma once,在第一种情况下不会.

如果您#undef SOME_HEADER_H并通过同一TU再次包含文件,则会看到功能上的差异:

#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"

现在,在情况1中,我具有头文件中的所有定义.在第二种情况下我没有.

即使没有#undef,您也可以想象到由于在情况1中忽略了#pragma once而导致预处理时间有所不同.这取决于实现.

我可以想到在第一次包含此头文件之前已经定义了两种可能的方式:

  • (显而易见的一个)是一个完全独立的文件,有意或通过偶然的名称冲突对其进行了定义,
  • 该文件的副本已定义.取决于实现方式,其中可能包括该文件以两个不同的文件名(例如,文件名)包含在同一个TU中的情况.由于符号链接或文件系统合并.如果您的实现支持#pragma once,并且您非常仔细地检查了其文档,则可能可以找到确定的声明,是通过包含文件的路径还是通过比较确定文件存储的方式来应用优化,如inode号.如果是后者,您甚至可以找出是否还有可能被骗来欺骗预处理器的骗局,例如远程安装本地文件系统以隐瞒它实际上是同一文件" ...

以预期的方式使用,但是没有区别,只要实现以Microsoft定义方式对待#pragma once即可.只要处理而不是跳过它,它都会标记包含优化的文件,因此,是否在文件的第二遍处理中都没有关系-第二遍不会发生.

当然,由于编译指示是非标准的,因此至少在理论上它在不同的实现上可能具有完全不同的含义,在这种情况下,它可能会在何时执行多少次很重要.实际上,您会认为没有人会这样做.

Is there any difference between placing the #pragma once inside the include guards as opposed to outside?

case 1:

#ifndef SOME_HEADER_H
#define SOME_HEADER_H
#pragma once

case 2:

#pragma once
#ifndef SOME_HEADER_H
#define SOME_HEADER_H

I'm just wondering out of curiosity if there's any special cases where I should prefer one or the other (case 1 or case 2) since I've decided to combine both (pragma and header guards) in my code.

EDIT:

I think you guys are misinterpreting my question... I am asking about the location of pragma once, not pragma once -vs- header guards.

解决方案

There's a subtle difference in that if SOME_HEADER_H is already defined before the header is included, then in the second case the preprocessor will process the #pragma once, and in the first case it won't.

You'll see a functional difference if you #undef SOME_HEADER_H and include the file again by the same TU:

#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"

Now, in case 1 I have all the definitions from the header file. In case 2 I don't.

Even without the #undef, you could conceivably see a difference in preprocessing time due to the #pragma once being ignored in case 1. That's up to the implementation.

I can think of two plausible ways it could already be defined before the first inclusion of this header file:

  • (the obvious one) a completely separate file defines it, either deliberately or by accidental name clash,
  • a copy of this file has already defined it. Depending on implementation that might include the case where this file gets involved in the same TU under two different filenames, e.g. because of a symbolic link or filesystem merge. If your implementation supports #pragma once, and you examine its documentation very carefully, you may be able to find a definitive statement whether the optimization is applied by the path under which the file is included, or by comparison of something which identifies a file's storage, like inode number. If the latter, you may even be able to figure out whether there are still scams that could be pulled to trick the preprocessor, such as remote-mounting a local filesystem to conceal that it's "the same file really"...

Used in the expected way, though, there's no difference provided that the implementation treats #pragma once in the way that Microsoft defines it. As long as it's processed rather than skipped, it marks the containing file for the optimization, so it doesn't matter whether or not it would be processed on a second pass through the file -- the second pass won't happen.

And of course since the pragma is non-standard, at least in theory it could have a completely different meaning on different implementations, in which case it might matter when and how many times it is processed. In practice, you'd think nobody will do that.

这篇关于内外兼备警卫之间的语用差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆