在结构定义中使用保护宏的含义是什么

时间:2019-01-20 14:23:57

标签: c++

我已经看到头文件代码是这样的:

#ifndef GS
#define GS

struct GS gs {
public:
    int n;
    gs(int n) : n{ n } {}
};

#endif // !GS

GS中使用struct GS gs的目的是什么?如果我将其删除,则代码的工作原理完全相同。

我对C ++很陌生。我试图在Google上搜索此搜索,但没有成功。

4 个答案:

答案 0 :(得分:3)

您是对的,代码的行为没有改变。 您显示的代码没有明显好处。

这是因为

#define GS

GS定义为 ,因此,在预处理程序完成之后,与在结构的声明中不包括它没有区别。

struct gs {

可能的原因是,如果还有其他工具可以在预处理器之前读取代码并标记某种用法。

注意:在注释中,您引用其他代码。根据其他标志,该代码可以将宏设置为 something ,例如BOOST_SYMBOL_EXPORT。那可能具有特定的含义。这些用法通常用于将类标记为导出或导入,具体取决于编译器当时的工作。

答案 1 :(得分:1)

根据您的评论,请参考以下内容:

struct TORRENT_EXPORT storage_interface {
}

TORRENT_EXPORT可能被定义为#define TORRENT_EXPORT

这类宏用于启用系统/编译/环境相关的选项。

如果使用TORRENT_EXPORT来启用符号导出(如果应将其用作动态链接库)

#if defined(_MSC_VER)
    //  Microsoft 
    #define TORRENT_EXPORT __declspec(dllexport)
    #define TORRENT_IMPORT __declspec(dllimport)
#elif defined(__GNUC__)
    //  GCC
    #define TORRENT_EXPORT __attribute__((visibility("default")))
    #define TORRENT_IMPORT
#else
    #define TORRENT_EXPORT
    #define TORRENT_IMPORT
    #pragma warning Unknown dynamic link import/export semantics.
#endif

或可用于其他预处理或后期处理脚本,作为标记,以更轻松地找到定义。 (例如,创建API文档,创建与脚本语言的粘合API等)

在其他情况下,仅当编译器支持语言功能时,它才用于启用语言功能(例如constexpr

答案 2 :(得分:0)

此类代码的唯一可见好处是确保将宏用于卫兵的目的,甚至是偶然使用
请参见以下情形:

// file1.h
#define GS 1234

// file2.h    
#ifndef GS
#define GS  // defined for the guarding purpose

#include"file1.h"  // "GS" re-defined for different purpose  

// the redefinition will result in compiler error, due to adding guard in `struct` definition
struct GS gs { ... };

#endif

现代编译器会警告您重新定义宏。

尽管如此,这样的防护措施也不会造成任何损害,并且为避免意外重新定义提供了一点好处。
通常,现代IDE会以独特的方式创建防护,其中包括带有额外下划线_的文件扩展名,例如:

#ifndef GS_H_
#define GS_H_

因此,可能不需要进行这种额外的检查,因为任何开发人员都不会倾向于创建类似文件的宏。

答案 3 :(得分:0)

宏的目的是由预处理器将其替换为其他任何东西(无论该宏定义为什么)。

具体来说,在类键和类名之间放置一个宏(例如在您的示例中),将使该宏控制类的属性序列。例如,如果您将宏定义为空(例如在您的示例中),则该类将具有空的属性序列:

case class Foo(id: String, `type`: String, color: String)

但是可以将宏定义为非空

#define GS
struct GS gs {
// same as
struct gs {

可以在编译时将宏作为参数传递给工具链,从而启用或禁用功能。宏还可以用于检测目标系统,从而启用系统特定的代码-从而允许依赖于系统的程序在多个系统上工作。


宏的另一个目的是防止头文件被两次包含。这样的宏称为标题保护。将相同的宏用作标头保护和内容替换(例如您的示例)既令人困惑又不合常规。