How to detect if C code (which needs 'extern C') is compiled in C++
I have a C header as part of a C++ library.
This C header would only make sense compiled by a C compiler, or by a C++ compiler within an extern "C" { ... }
block, otherwise unresolved link errors would happen.
I thought to add a block such as:
#ifdef __cplusplus
#error "Compiling C bindings with C++ (forgot 'extern "C"'?)"
#endif
in the C header, but unfortunately the __cplusplus
macro is defined also within an extern "C" { ... }
block.
Is there another way to detect this condition correctly?
c++ c extern
add a comment |
I have a C header as part of a C++ library.
This C header would only make sense compiled by a C compiler, or by a C++ compiler within an extern "C" { ... }
block, otherwise unresolved link errors would happen.
I thought to add a block such as:
#ifdef __cplusplus
#error "Compiling C bindings with C++ (forgot 'extern "C"'?)"
#endif
in the C header, but unfortunately the __cplusplus
macro is defined also within an extern "C" { ... }
block.
Is there another way to detect this condition correctly?
c++ c extern
You mean detecting the C++ part and check that extern was declared? No way to detect this. Just put the extern C.
– Matthieu Brucher
Mar 11 at 10:35
add a comment |
I have a C header as part of a C++ library.
This C header would only make sense compiled by a C compiler, or by a C++ compiler within an extern "C" { ... }
block, otherwise unresolved link errors would happen.
I thought to add a block such as:
#ifdef __cplusplus
#error "Compiling C bindings with C++ (forgot 'extern "C"'?)"
#endif
in the C header, but unfortunately the __cplusplus
macro is defined also within an extern "C" { ... }
block.
Is there another way to detect this condition correctly?
c++ c extern
I have a C header as part of a C++ library.
This C header would only make sense compiled by a C compiler, or by a C++ compiler within an extern "C" { ... }
block, otherwise unresolved link errors would happen.
I thought to add a block such as:
#ifdef __cplusplus
#error "Compiling C bindings with C++ (forgot 'extern "C"'?)"
#endif
in the C header, but unfortunately the __cplusplus
macro is defined also within an extern "C" { ... }
block.
Is there another way to detect this condition correctly?
c++ c extern
c++ c extern
asked Mar 11 at 10:22
fferrifferri
12k32453
12k32453
You mean detecting the C++ part and check that extern was declared? No way to detect this. Just put the extern C.
– Matthieu Brucher
Mar 11 at 10:35
add a comment |
You mean detecting the C++ part and check that extern was declared? No way to detect this. Just put the extern C.
– Matthieu Brucher
Mar 11 at 10:35
You mean detecting the C++ part and check that extern was declared? No way to detect this. Just put the extern C.
– Matthieu Brucher
Mar 11 at 10:35
You mean detecting the C++ part and check that extern was declared? No way to detect this. Just put the extern C.
– Matthieu Brucher
Mar 11 at 10:35
add a comment |
1 Answer
1
active
oldest
votes
The common practice is not to demand client code wraps your header in extern "C"
, but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.
14
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting theextern "C"
.
– StoryTeller
Mar 11 at 11:15
12
Such a shame thatC
doesn't supportextern "C"
...
– Rakete1111
Mar 11 at 11:36
16
@Rakete1111 - We shouldn't throw stones from our glass house that has norestrict
qualifier :P
– StoryTeller
Mar 11 at 12:00
12
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
1
@jxh Language linkage supports more than just"C"
and"C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.
– Angew
Mar 12 at 10:42
|
show 11 more comments
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%2f55099677%2fhow-to-detect-if-c-code-which-needs-extern-c-is-compiled-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The common practice is not to demand client code wraps your header in extern "C"
, but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.
14
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting theextern "C"
.
– StoryTeller
Mar 11 at 11:15
12
Such a shame thatC
doesn't supportextern "C"
...
– Rakete1111
Mar 11 at 11:36
16
@Rakete1111 - We shouldn't throw stones from our glass house that has norestrict
qualifier :P
– StoryTeller
Mar 11 at 12:00
12
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
1
@jxh Language linkage supports more than just"C"
and"C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.
– Angew
Mar 12 at 10:42
|
show 11 more comments
The common practice is not to demand client code wraps your header in extern "C"
, but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.
14
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting theextern "C"
.
– StoryTeller
Mar 11 at 11:15
12
Such a shame thatC
doesn't supportextern "C"
...
– Rakete1111
Mar 11 at 11:36
16
@Rakete1111 - We shouldn't throw stones from our glass house that has norestrict
qualifier :P
– StoryTeller
Mar 11 at 12:00
12
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
1
@jxh Language linkage supports more than just"C"
and"C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.
– Angew
Mar 12 at 10:42
|
show 11 more comments
The common practice is not to demand client code wraps your header in extern "C"
, but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.
The common practice is not to demand client code wraps your header in extern "C"
, but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.
answered Mar 11 at 10:27
StoryTellerStoryTeller
102k12215279
102k12215279
14
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting theextern "C"
.
– StoryTeller
Mar 11 at 11:15
12
Such a shame thatC
doesn't supportextern "C"
...
– Rakete1111
Mar 11 at 11:36
16
@Rakete1111 - We shouldn't throw stones from our glass house that has norestrict
qualifier :P
– StoryTeller
Mar 11 at 12:00
12
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
1
@jxh Language linkage supports more than just"C"
and"C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.
– Angew
Mar 12 at 10:42
|
show 11 more comments
14
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting theextern "C"
.
– StoryTeller
Mar 11 at 11:15
12
Such a shame thatC
doesn't supportextern "C"
...
– Rakete1111
Mar 11 at 11:36
16
@Rakete1111 - We shouldn't throw stones from our glass house that has norestrict
qualifier :P
– StoryTeller
Mar 11 at 12:00
12
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
1
@jxh Language linkage supports more than just"C"
and"C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.
– Angew
Mar 12 at 10:42
14
14
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting the
extern "C"
.– StoryTeller
Mar 11 at 11:15
@pmg - Not in C++. If you nest language linkage specifications, the innermost "wins". The macro is just to prevent a C compiler from rightfully rejecting the
extern "C"
.– StoryTeller
Mar 11 at 11:15
12
12
Such a shame that
C
doesn't support extern "C"
...– Rakete1111
Mar 11 at 11:36
Such a shame that
C
doesn't support extern "C"
...– Rakete1111
Mar 11 at 11:36
16
16
@Rakete1111 - We shouldn't throw stones from our glass house that has no
restrict
qualifier :P– StoryTeller
Mar 11 at 12:00
@Rakete1111 - We shouldn't throw stones from our glass house that has no
restrict
qualifier :P– StoryTeller
Mar 11 at 12:00
12
12
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
@SeñorCMasMas - It also tells it to adhere to a C calling convention (those may differ). And the point that was made is that it'd be nice if C compilers didn't reject the syntax outright, but instead treated it as a no-op. So the macro business won't be needed.
– StoryTeller
Mar 11 at 16:21
1
1
@jxh Language linkage supports more than just
"C"
and "C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.– Angew
Mar 12 at 10:42
@jxh Language linkage supports more than just
"C"
and "C++"
; compilers are free to support any toerh language linkage specification. I'd say using a string literal for this is better than introducing a new keyword for each.– Angew
Mar 12 at 10:42
|
show 11 more comments
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%2f55099677%2fhow-to-detect-if-c-code-which-needs-extern-c-is-compiled-in-c%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
You mean detecting the C++ part and check that extern was declared? No way to detect this. Just put the extern C.
– Matthieu Brucher
Mar 11 at 10:35