What is the meaning of the using guard macro in struct definition
I have seen header file code something like this:
#ifndef GS
#define GS
struct GS gs {
public:
int n;
gs(int n) : n{ n } {}
};
#endif // !GS
What is the purpose of using GS
in struct GS gs
? The code works exactly the same if I remove it.
I am pretty new to C++. I tried to search this on google without success.
c++
|
show 6 more comments
I have seen header file code something like this:
#ifndef GS
#define GS
struct GS gs {
public:
int n;
gs(int n) : n{ n } {}
};
#endif // !GS
What is the purpose of using GS
in struct GS gs
? The code works exactly the same if I remove it.
I am pretty new to C++. I tried to search this on google without success.
c++
1
In the code you show, there's no point. Where did you see this pattern?
– Some programmer dude
Jan 20 at 14:29
1
@GurwinderSingh that's a different thing. TORRENT_EXPORT is probably defined as dllexport or dllimport which are reserved keywords that tells the compiler if the method is available outside the .dll or not. Search for "declspec".
– AlexG
Jan 20 at 14:33
1
That's one place of definition. But note how it's guarded with an#ifndef
? On some platforms and compilers (typically on Windows) it might already be defined to something else. Widen your search. As mentioned by @AlexG, it's probably defined as__declspec(dllexport)
or__declspec(dllimport)
or similar (depending on if the header files are used for creating a DLL or not).
– Some programmer dude
Jan 20 at 14:40
1
@GurwinderSingh The definition on lines 88-90 is a "catch-all" definition that makes the code correct if the symbol wasn't already set in lines 68-72 or earlier.
– molbdnilo
Jan 20 at 14:41
2
@GurwinderSingh It'll be defined somewhere else as part of build scripts that might define TORRENT_EXPORT as an argument when running the compiler, depending on the compiler and operating system it's cocompiled on, it'll mark the struct to be exported when build ing a .dll .You should rather ask about this specific code in libtorrent rather than your made up example - it'll be much clearer to people what that specific purpose is.
– nos
Jan 20 at 14:43
|
show 6 more comments
I have seen header file code something like this:
#ifndef GS
#define GS
struct GS gs {
public:
int n;
gs(int n) : n{ n } {}
};
#endif // !GS
What is the purpose of using GS
in struct GS gs
? The code works exactly the same if I remove it.
I am pretty new to C++. I tried to search this on google without success.
c++
I have seen header file code something like this:
#ifndef GS
#define GS
struct GS gs {
public:
int n;
gs(int n) : n{ n } {}
};
#endif // !GS
What is the purpose of using GS
in struct GS gs
? The code works exactly the same if I remove it.
I am pretty new to C++. I tried to search this on google without success.
c++
c++
asked Jan 20 at 14:23
Gurwinder SinghGurwinder Singh
31.6k52647
31.6k52647
1
In the code you show, there's no point. Where did you see this pattern?
– Some programmer dude
Jan 20 at 14:29
1
@GurwinderSingh that's a different thing. TORRENT_EXPORT is probably defined as dllexport or dllimport which are reserved keywords that tells the compiler if the method is available outside the .dll or not. Search for "declspec".
– AlexG
Jan 20 at 14:33
1
That's one place of definition. But note how it's guarded with an#ifndef
? On some platforms and compilers (typically on Windows) it might already be defined to something else. Widen your search. As mentioned by @AlexG, it's probably defined as__declspec(dllexport)
or__declspec(dllimport)
or similar (depending on if the header files are used for creating a DLL or not).
– Some programmer dude
Jan 20 at 14:40
1
@GurwinderSingh The definition on lines 88-90 is a "catch-all" definition that makes the code correct if the symbol wasn't already set in lines 68-72 or earlier.
– molbdnilo
Jan 20 at 14:41
2
@GurwinderSingh It'll be defined somewhere else as part of build scripts that might define TORRENT_EXPORT as an argument when running the compiler, depending on the compiler and operating system it's cocompiled on, it'll mark the struct to be exported when build ing a .dll .You should rather ask about this specific code in libtorrent rather than your made up example - it'll be much clearer to people what that specific purpose is.
– nos
Jan 20 at 14:43
|
show 6 more comments
1
In the code you show, there's no point. Where did you see this pattern?
– Some programmer dude
Jan 20 at 14:29
1
@GurwinderSingh that's a different thing. TORRENT_EXPORT is probably defined as dllexport or dllimport which are reserved keywords that tells the compiler if the method is available outside the .dll or not. Search for "declspec".
– AlexG
Jan 20 at 14:33
1
That's one place of definition. But note how it's guarded with an#ifndef
? On some platforms and compilers (typically on Windows) it might already be defined to something else. Widen your search. As mentioned by @AlexG, it's probably defined as__declspec(dllexport)
or__declspec(dllimport)
or similar (depending on if the header files are used for creating a DLL or not).
– Some programmer dude
Jan 20 at 14:40
1
@GurwinderSingh The definition on lines 88-90 is a "catch-all" definition that makes the code correct if the symbol wasn't already set in lines 68-72 or earlier.
– molbdnilo
Jan 20 at 14:41
2
@GurwinderSingh It'll be defined somewhere else as part of build scripts that might define TORRENT_EXPORT as an argument when running the compiler, depending on the compiler and operating system it's cocompiled on, it'll mark the struct to be exported when build ing a .dll .You should rather ask about this specific code in libtorrent rather than your made up example - it'll be much clearer to people what that specific purpose is.
– nos
Jan 20 at 14:43
1
1
In the code you show, there's no point. Where did you see this pattern?
– Some programmer dude
Jan 20 at 14:29
In the code you show, there's no point. Where did you see this pattern?
– Some programmer dude
Jan 20 at 14:29
1
1
@GurwinderSingh that's a different thing. TORRENT_EXPORT is probably defined as dllexport or dllimport which are reserved keywords that tells the compiler if the method is available outside the .dll or not. Search for "declspec".
– AlexG
Jan 20 at 14:33
@GurwinderSingh that's a different thing. TORRENT_EXPORT is probably defined as dllexport or dllimport which are reserved keywords that tells the compiler if the method is available outside the .dll or not. Search for "declspec".
– AlexG
Jan 20 at 14:33
1
1
That's one place of definition. But note how it's guarded with an
#ifndef
? On some platforms and compilers (typically on Windows) it might already be defined to something else. Widen your search. As mentioned by @AlexG, it's probably defined as __declspec(dllexport)
or __declspec(dllimport)
or similar (depending on if the header files are used for creating a DLL or not).– Some programmer dude
Jan 20 at 14:40
That's one place of definition. But note how it's guarded with an
#ifndef
? On some platforms and compilers (typically on Windows) it might already be defined to something else. Widen your search. As mentioned by @AlexG, it's probably defined as __declspec(dllexport)
or __declspec(dllimport)
or similar (depending on if the header files are used for creating a DLL or not).– Some programmer dude
Jan 20 at 14:40
1
1
@GurwinderSingh The definition on lines 88-90 is a "catch-all" definition that makes the code correct if the symbol wasn't already set in lines 68-72 or earlier.
– molbdnilo
Jan 20 at 14:41
@GurwinderSingh The definition on lines 88-90 is a "catch-all" definition that makes the code correct if the symbol wasn't already set in lines 68-72 or earlier.
– molbdnilo
Jan 20 at 14:41
2
2
@GurwinderSingh It'll be defined somewhere else as part of build scripts that might define TORRENT_EXPORT as an argument when running the compiler, depending on the compiler and operating system it's cocompiled on, it'll mark the struct to be exported when build ing a .dll .You should rather ask about this specific code in libtorrent rather than your made up example - it'll be much clearer to people what that specific purpose is.
– nos
Jan 20 at 14:43
@GurwinderSingh It'll be defined somewhere else as part of build scripts that might define TORRENT_EXPORT as an argument when running the compiler, depending on the compiler and operating system it's cocompiled on, it'll mark the struct to be exported when build ing a .dll .You should rather ask about this specific code in libtorrent rather than your made up example - it'll be much clearer to people what that specific purpose is.
– nos
Jan 20 at 14:43
|
show 6 more comments
4 Answers
4
active
oldest
votes
You are right that there is no change in the behavior of the code.
There is no apparent benefit from the code you show.
This is because
#define GS
Defines GS
as nothing, so after the preprocessor finishes, there is no difference from not including it in the declaration of the struct.
struct gs {
What could be the reason would be if there is some other tool that reads the code before the preprocessor and marks some kind of usage.
Note: in the comments, you reference other code. That code may, depending on other flags, set the macro to something, such as BOOST_SYMBOL_EXPORT
. That then may have specific meaning. These kinds of usage are often used for marking classes as export or import depending on what the compiler is doing at the time.
add a comment |
Base on your comment your refer to this:
struct TORRENT_EXPORT storage_interface {
}
Where TORRENT_EXPORT
might be defined as #define TORRENT_EXPORT
These kind of macros are use to enable system/compile/environment dependent options.
In case of TORRENT_EXPORT
to enable the export of the symbols if it should be use as dynamic linke library:
#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
Or can be used for other pre or post processing scripts as markers to find the definitions easier. (e.g. to create API documentations, to create glue APIs to scripting languages, ...)
In other cases it is used to enable language features only if the compiler supports it (like constexpr
)
add a comment |
The only visible benefit for such code is to make sure that the macro is used for the purpose of guards and nothing else, even accidentally.
See below scenario:
// 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
Modern compilers will give warning for re-define of a macro.
Nevertheless, such guard doesn't harm in anyway and provides a little benefit to avoid any accidental redefinition.
Usually modern IDE-s will create the guard in a unique way, which includes the file extension with extra underscores _
such as:
#ifndef GS_H_
#define GS_H_
Hence, such extra check may not be required, because any developer wouldn't tend to create the file-like macros.
add a comment |
A purpose of a macro is that it is replaced by something else (whatever that macro is defined to be) by the pre processor.
Specifically, placing a macro between class-key and the class name (such as in your example), will let the macro control the attribute sequence of the class. For example, if you define the macro to be empty (such as in your example), then the class will have an empty attribute sequence:
#define GS
struct GS gs {
// same as
struct gs {
But a macro can be defined to be non-empty:
#define GS alignas(8)
struct GS gs {
// same as
struct alignas(8) gs {
Macros can be passed as an argument to the tool chain upon compilation, thereby toggling a feature on or off. Macros can also be used to detect the target system and thereby enable system specific code - thereby allowing a system dependent program work on multiple systems.
Another purpose of a macro is to prevent a header from being included twice. Such macro is called a header guard. Using the same macro for both a header guard, and content replacement (such as in your example) is confusing and unconventional.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54277415%2fwhat-is-the-meaning-of-the-using-guard-macro-in-struct-definition%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are right that there is no change in the behavior of the code.
There is no apparent benefit from the code you show.
This is because
#define GS
Defines GS
as nothing, so after the preprocessor finishes, there is no difference from not including it in the declaration of the struct.
struct gs {
What could be the reason would be if there is some other tool that reads the code before the preprocessor and marks some kind of usage.
Note: in the comments, you reference other code. That code may, depending on other flags, set the macro to something, such as BOOST_SYMBOL_EXPORT
. That then may have specific meaning. These kinds of usage are often used for marking classes as export or import depending on what the compiler is doing at the time.
add a comment |
You are right that there is no change in the behavior of the code.
There is no apparent benefit from the code you show.
This is because
#define GS
Defines GS
as nothing, so after the preprocessor finishes, there is no difference from not including it in the declaration of the struct.
struct gs {
What could be the reason would be if there is some other tool that reads the code before the preprocessor and marks some kind of usage.
Note: in the comments, you reference other code. That code may, depending on other flags, set the macro to something, such as BOOST_SYMBOL_EXPORT
. That then may have specific meaning. These kinds of usage are often used for marking classes as export or import depending on what the compiler is doing at the time.
add a comment |
You are right that there is no change in the behavior of the code.
There is no apparent benefit from the code you show.
This is because
#define GS
Defines GS
as nothing, so after the preprocessor finishes, there is no difference from not including it in the declaration of the struct.
struct gs {
What could be the reason would be if there is some other tool that reads the code before the preprocessor and marks some kind of usage.
Note: in the comments, you reference other code. That code may, depending on other flags, set the macro to something, such as BOOST_SYMBOL_EXPORT
. That then may have specific meaning. These kinds of usage are often used for marking classes as export or import depending on what the compiler is doing at the time.
You are right that there is no change in the behavior of the code.
There is no apparent benefit from the code you show.
This is because
#define GS
Defines GS
as nothing, so after the preprocessor finishes, there is no difference from not including it in the declaration of the struct.
struct gs {
What could be the reason would be if there is some other tool that reads the code before the preprocessor and marks some kind of usage.
Note: in the comments, you reference other code. That code may, depending on other flags, set the macro to something, such as BOOST_SYMBOL_EXPORT
. That then may have specific meaning. These kinds of usage are often used for marking classes as export or import depending on what the compiler is doing at the time.
edited Jan 20 at 14:39
answered Jan 20 at 14:32
crashmstrcrashmstr
23.9k75274
23.9k75274
add a comment |
add a comment |
Base on your comment your refer to this:
struct TORRENT_EXPORT storage_interface {
}
Where TORRENT_EXPORT
might be defined as #define TORRENT_EXPORT
These kind of macros are use to enable system/compile/environment dependent options.
In case of TORRENT_EXPORT
to enable the export of the symbols if it should be use as dynamic linke library:
#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
Or can be used for other pre or post processing scripts as markers to find the definitions easier. (e.g. to create API documentations, to create glue APIs to scripting languages, ...)
In other cases it is used to enable language features only if the compiler supports it (like constexpr
)
add a comment |
Base on your comment your refer to this:
struct TORRENT_EXPORT storage_interface {
}
Where TORRENT_EXPORT
might be defined as #define TORRENT_EXPORT
These kind of macros are use to enable system/compile/environment dependent options.
In case of TORRENT_EXPORT
to enable the export of the symbols if it should be use as dynamic linke library:
#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
Or can be used for other pre or post processing scripts as markers to find the definitions easier. (e.g. to create API documentations, to create glue APIs to scripting languages, ...)
In other cases it is used to enable language features only if the compiler supports it (like constexpr
)
add a comment |
Base on your comment your refer to this:
struct TORRENT_EXPORT storage_interface {
}
Where TORRENT_EXPORT
might be defined as #define TORRENT_EXPORT
These kind of macros are use to enable system/compile/environment dependent options.
In case of TORRENT_EXPORT
to enable the export of the symbols if it should be use as dynamic linke library:
#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
Or can be used for other pre or post processing scripts as markers to find the definitions easier. (e.g. to create API documentations, to create glue APIs to scripting languages, ...)
In other cases it is used to enable language features only if the compiler supports it (like constexpr
)
Base on your comment your refer to this:
struct TORRENT_EXPORT storage_interface {
}
Where TORRENT_EXPORT
might be defined as #define TORRENT_EXPORT
These kind of macros are use to enable system/compile/environment dependent options.
In case of TORRENT_EXPORT
to enable the export of the symbols if it should be use as dynamic linke library:
#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
Or can be used for other pre or post processing scripts as markers to find the definitions easier. (e.g. to create API documentations, to create glue APIs to scripting languages, ...)
In other cases it is used to enable language features only if the compiler supports it (like constexpr
)
answered Jan 20 at 14:45
t.nieset.niese
21.8k63764
21.8k63764
add a comment |
add a comment |
The only visible benefit for such code is to make sure that the macro is used for the purpose of guards and nothing else, even accidentally.
See below scenario:
// 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
Modern compilers will give warning for re-define of a macro.
Nevertheless, such guard doesn't harm in anyway and provides a little benefit to avoid any accidental redefinition.
Usually modern IDE-s will create the guard in a unique way, which includes the file extension with extra underscores _
such as:
#ifndef GS_H_
#define GS_H_
Hence, such extra check may not be required, because any developer wouldn't tend to create the file-like macros.
add a comment |
The only visible benefit for such code is to make sure that the macro is used for the purpose of guards and nothing else, even accidentally.
See below scenario:
// 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
Modern compilers will give warning for re-define of a macro.
Nevertheless, such guard doesn't harm in anyway and provides a little benefit to avoid any accidental redefinition.
Usually modern IDE-s will create the guard in a unique way, which includes the file extension with extra underscores _
such as:
#ifndef GS_H_
#define GS_H_
Hence, such extra check may not be required, because any developer wouldn't tend to create the file-like macros.
add a comment |
The only visible benefit for such code is to make sure that the macro is used for the purpose of guards and nothing else, even accidentally.
See below scenario:
// 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
Modern compilers will give warning for re-define of a macro.
Nevertheless, such guard doesn't harm in anyway and provides a little benefit to avoid any accidental redefinition.
Usually modern IDE-s will create the guard in a unique way, which includes the file extension with extra underscores _
such as:
#ifndef GS_H_
#define GS_H_
Hence, such extra check may not be required, because any developer wouldn't tend to create the file-like macros.
The only visible benefit for such code is to make sure that the macro is used for the purpose of guards and nothing else, even accidentally.
See below scenario:
// 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
Modern compilers will give warning for re-define of a macro.
Nevertheless, such guard doesn't harm in anyway and provides a little benefit to avoid any accidental redefinition.
Usually modern IDE-s will create the guard in a unique way, which includes the file extension with extra underscores _
such as:
#ifndef GS_H_
#define GS_H_
Hence, such extra check may not be required, because any developer wouldn't tend to create the file-like macros.
answered Jan 20 at 14:40
iammilindiammilind
44.7k20125252
44.7k20125252
add a comment |
add a comment |
A purpose of a macro is that it is replaced by something else (whatever that macro is defined to be) by the pre processor.
Specifically, placing a macro between class-key and the class name (such as in your example), will let the macro control the attribute sequence of the class. For example, if you define the macro to be empty (such as in your example), then the class will have an empty attribute sequence:
#define GS
struct GS gs {
// same as
struct gs {
But a macro can be defined to be non-empty:
#define GS alignas(8)
struct GS gs {
// same as
struct alignas(8) gs {
Macros can be passed as an argument to the tool chain upon compilation, thereby toggling a feature on or off. Macros can also be used to detect the target system and thereby enable system specific code - thereby allowing a system dependent program work on multiple systems.
Another purpose of a macro is to prevent a header from being included twice. Such macro is called a header guard. Using the same macro for both a header guard, and content replacement (such as in your example) is confusing and unconventional.
add a comment |
A purpose of a macro is that it is replaced by something else (whatever that macro is defined to be) by the pre processor.
Specifically, placing a macro between class-key and the class name (such as in your example), will let the macro control the attribute sequence of the class. For example, if you define the macro to be empty (such as in your example), then the class will have an empty attribute sequence:
#define GS
struct GS gs {
// same as
struct gs {
But a macro can be defined to be non-empty:
#define GS alignas(8)
struct GS gs {
// same as
struct alignas(8) gs {
Macros can be passed as an argument to the tool chain upon compilation, thereby toggling a feature on or off. Macros can also be used to detect the target system and thereby enable system specific code - thereby allowing a system dependent program work on multiple systems.
Another purpose of a macro is to prevent a header from being included twice. Such macro is called a header guard. Using the same macro for both a header guard, and content replacement (such as in your example) is confusing and unconventional.
add a comment |
A purpose of a macro is that it is replaced by something else (whatever that macro is defined to be) by the pre processor.
Specifically, placing a macro between class-key and the class name (such as in your example), will let the macro control the attribute sequence of the class. For example, if you define the macro to be empty (such as in your example), then the class will have an empty attribute sequence:
#define GS
struct GS gs {
// same as
struct gs {
But a macro can be defined to be non-empty:
#define GS alignas(8)
struct GS gs {
// same as
struct alignas(8) gs {
Macros can be passed as an argument to the tool chain upon compilation, thereby toggling a feature on or off. Macros can also be used to detect the target system and thereby enable system specific code - thereby allowing a system dependent program work on multiple systems.
Another purpose of a macro is to prevent a header from being included twice. Such macro is called a header guard. Using the same macro for both a header guard, and content replacement (such as in your example) is confusing and unconventional.
A purpose of a macro is that it is replaced by something else (whatever that macro is defined to be) by the pre processor.
Specifically, placing a macro between class-key and the class name (such as in your example), will let the macro control the attribute sequence of the class. For example, if you define the macro to be empty (such as in your example), then the class will have an empty attribute sequence:
#define GS
struct GS gs {
// same as
struct gs {
But a macro can be defined to be non-empty:
#define GS alignas(8)
struct GS gs {
// same as
struct alignas(8) gs {
Macros can be passed as an argument to the tool chain upon compilation, thereby toggling a feature on or off. Macros can also be used to detect the target system and thereby enable system specific code - thereby allowing a system dependent program work on multiple systems.
Another purpose of a macro is to prevent a header from being included twice. Such macro is called a header guard. Using the same macro for both a header guard, and content replacement (such as in your example) is confusing and unconventional.
edited Jan 20 at 14:56
answered Jan 20 at 14:48
eerorikaeerorika
81.4k559122
81.4k559122
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54277415%2fwhat-is-the-meaning-of-the-using-guard-macro-in-struct-definition%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
In the code you show, there's no point. Where did you see this pattern?
– Some programmer dude
Jan 20 at 14:29
1
@GurwinderSingh that's a different thing. TORRENT_EXPORT is probably defined as dllexport or dllimport which are reserved keywords that tells the compiler if the method is available outside the .dll or not. Search for "declspec".
– AlexG
Jan 20 at 14:33
1
That's one place of definition. But note how it's guarded with an
#ifndef
? On some platforms and compilers (typically on Windows) it might already be defined to something else. Widen your search. As mentioned by @AlexG, it's probably defined as__declspec(dllexport)
or__declspec(dllimport)
or similar (depending on if the header files are used for creating a DLL or not).– Some programmer dude
Jan 20 at 14:40
1
@GurwinderSingh The definition on lines 88-90 is a "catch-all" definition that makes the code correct if the symbol wasn't already set in lines 68-72 or earlier.
– molbdnilo
Jan 20 at 14:41
2
@GurwinderSingh It'll be defined somewhere else as part of build scripts that might define TORRENT_EXPORT as an argument when running the compiler, depending on the compiler and operating system it's cocompiled on, it'll mark the struct to be exported when build ing a .dll .You should rather ask about this specific code in libtorrent rather than your made up example - it'll be much clearer to people what that specific purpose is.
– nos
Jan 20 at 14:43