How to detect if C code (which needs 'extern C') is compiled in C++












34















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?










share|improve this question























  • 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


















34















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?










share|improve this question























  • 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
















34












34








34


7






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?










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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





















  • 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














1 Answer
1






active

oldest

votes


















94














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.






share|improve this answer



















  • 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








  • 12





    Such a shame that C doesn't support extern "C"...

    – Rakete1111
    Mar 11 at 11:36






  • 16





    @Rakete1111 - We shouldn't throw stones from our glass house that has no restrict 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











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
});


}
});














draft saved

draft discarded


















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









94














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.






share|improve this answer



















  • 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








  • 12





    Such a shame that C doesn't support extern "C"...

    – Rakete1111
    Mar 11 at 11:36






  • 16





    @Rakete1111 - We shouldn't throw stones from our glass house that has no restrict 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
















94














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.






share|improve this answer



















  • 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








  • 12





    Such a shame that C doesn't support extern "C"...

    – Rakete1111
    Mar 11 at 11:36






  • 16





    @Rakete1111 - We shouldn't throw stones from our glass house that has no restrict 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














94












94








94







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










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 the extern "C".

    – StoryTeller
    Mar 11 at 11:15








  • 12





    Such a shame that C doesn't support extern "C"...

    – Rakete1111
    Mar 11 at 11:36






  • 16





    @Rakete1111 - We shouldn't throw stones from our glass house that has no restrict 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





    @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





    Such a shame that C doesn't support extern "C"...

    – Rakete1111
    Mar 11 at 11:36






  • 16





    @Rakete1111 - We shouldn't throw stones from our glass house that has no restrict 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

How to change which sound is reproduced for terminal bell?

Can I use Tabulator js library in my java Spring + Thymeleaf project?

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents