简体   繁体   中英

Including C headers in a C++ namespace - is it a standard behavior?

I have been believed that C header files must be included in the top level of C++ program. Anyway, I accidentally discovered that C++ is allowing inclusion of C headers in a sub namespace.

namespace AAA {
    extern "C" {
        #include "sqlite3.h"     // C API.
    }
}

And then, all the C types and functions will be placed in the namespace. More interestingly, all the linked C functions are also just working! I also discovered that this may cause some preprocessor issue, but except that, it seems to be working pretty fine.

Is this a standard behavior? (I am using Clang 3.x) If it is, what is the name of this feature and where can I find this feature mentioned in the standard?

You may even do strange things like

//test.c
int
    #include "main.h"
{
    return 1;
}

//main.h
main(void)

The preprocessor macros are expanded before any syntax check is done. The above example will expand to

int
main(void)
{
    return 1;
}

which is legal code. While you really should avoid such examples, there are cases, where including into another element is quite useful. In your question it depends on how the names are mangled during compilation. If all the definitions in your header file are declared with extern "C" , the names will be searched unmangled in the object file, this is, however, not the case if the object file containing the implementation does not use the same namespace as it's definition in the consuming code and does not declare it extern "C" .

Is this a standard behavior?

Yes - the behaviour is supported by the Standard, as the C++ compiler doesn't really have a notion of code being "C" versus "C++" except when extern "C" is used to inhibit namespace mangling.

The consequence of not inhibiting mangling is that you may end up with "unresolved symbol" errors at link time if you try to link with a C library defining the out-of-line symbols ( extern variables, functions) mentioned in the header.

If it is [a Standard feature], what is the name of this feature and where can I find this feature mentioned in the standard?

This is just a consequence of the way #include works, which is defined in 16.2 Source file inclusion [cpp.include], crucially:

[an #include ] causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters.

So, whatever happens with the "C" header is exactly as if the surrounding namespace / extern statements and braces existed at the top and bottom of the header file instead... by the time the next phase on compilation begins it's irrelevant exactly where the source code came from (except for purposes of displaying error messages that properly relate to the source file).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM