【问题标题】:in C++ , what's so special about "_MOVE_H"?在 C++ 中,“_MOVE_H”有什么特别之处?
【发布时间】:2011-03-21 16:25:19
【问题描述】:

我有一个这样的 C++ 文件

#ifndef _MOVE_H
#define _MOVE_H

class Move {
    int x, y;
public:
    Move(int initX = 0, int initY = 0) : x(initX), y(initY) {}
    int getX() { return x; }
    void setX(int newX) { x = newX; }
    int getY() { return y; }
    void setY(int newY) { y = newY; }
};

#endif

令我惊讶的是,#ifndef#endif 之间的所有代码都被编译器忽略了(我发誓我没有在其他任何地方定义 _MOVE_H),而且我有各种关于缺少定义的错误.我在想我做错了什么,但是当我尝试使用另一个键时(比如_MOVE_Ha,一切都恢复正常了。_MOVE_H 是否意味着 C++ 中的特殊内容?

我正在运行 Ubuntu 10.04、GCC 4.4.3,如果这很重要的话。

谢谢,

【问题讨论】:

  • 可能是您包含的库文件之一,使用它作为包含保护?你检查了吗?顺便说一句,我通常会在它前面加上项目名称,以避免出现此类问题。
  • 另一个使用#pragma once而不是#define的理由包括警卫...
  • @Inverse, #pragma once 是编译器扩展,并非所有编译器都支持。包含保护是唯一安全的独立于编译器的防止多重包含的方法。
  • @Nathan Ernst:我知道,但是如果您使用 3 个主要编译器中的任何一个,#pragma once 使编译器不必在每次编译时都打开和处理相同的受保护标头。
  • 编译器也不需要打开和处理普通的头文件。识别包含守卫的想法是十多年前发明并实施的,IIRC。

标签: c++ include-guards


【解决方案1】:

任何以下划线开头的大写字母都保留给实现。 (即_M)。我认为总的来说,您希望远离前导下划线。

【讨论】:

    【解决方案2】:

    我相信 gcc 有一个名为 move.h 的包含文件,其中包含标记 _MOVE_H。想必你已经和这个发生了冲突。使用不同的标识符,最好是不以下划线开头的标识符。我在我的里面放了一个 GUID,但后来我 真的 着迷 :-)

    【讨论】:

      【解决方案3】:

      只需在您的机器上运行 /usr/include/c++ 中的 grep _MOVE_H

      对我来说:

      c++/4.5.0/bits/move.h:#ifndef _MOVE_H
      

      根据经验,不要使用以___ 为前缀的things(实际上是任何东西)。它保留供内部使用。 使用SOMETHING_MOVE_H(通常是公司名称,...)。

      我猜这是一个新的头文件,用于将移动语义添加到 c++0x。

      【讨论】:

      • 为了澄清下划线规则,保留以下内容:任何以_ 为前缀的全局 名称,任何以__ 为前缀的任何名称,以及任何名称以_ 为前缀并以大写字母开头的任何类型。 OP 违反了第一条和第三条规则。
      • 保留任何包含__ 的名称。它不需要前缀。
      【解决方案4】:

      防止同一个头文件被多次包含是一个技巧。您 #define 的实际值无关紧要 - 只要它仅在该头文件中定义,约定是大写的 NAME_HEADER_FILE_H

      另请参阅#pragma once 上的此讨论

      【讨论】:

      • 抱歉,这不是问题所在。问题是,我的文件根本不包括在内。
      猜你喜欢
      • 2011-04-18
      • 2017-02-19
      • 2016-09-30
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      相关资源
      最近更新 更多