Reputation: 10343
If you use extern C
it with C++ files, does that allow defined C behavior that is undefined in C++?
blah.h
extern "C"
{
struct x {
int blah;
char buf[];
};
char * get_buf(struct x * base);
struct x * make_struct(int blah, int size);
}
some_random.cpp
#include "blah.h"
...
x * data=make_struct(7, 12);
std::strcpy(get_buf(data), "hello");
Is using the defined behavior in C's flexible array member, defined behavior when used this way?
Upvotes: 14
Views: 1163
Reputation: 263627
Flexible array members are a standard feature of C, starting with the 1999 standard. They do not exist in C++.
Your code is not valid C++. Wrapping it in extern "C"
doesn't change that. A conforming C++ compiler must at least warn about it, and arguably should reject it.
It happens that g++ implements C-style flexible array members as an extension to C++. That's perfectly legitimate (compilers are allowed to implement extensions), but its use is not portable. Its behavior, like that of any language extension, is defined by the compiler, not by the language.
If you compile it with g++ -pedantic
, you'll get a warning:
c.cpp:5:21: warning: ISO C++ forbids zero-size array ‘buf’ [-Wpedantic]
char buf[];
^
If you want to use C-style flexible array members in a C++ program without relying on a compiler-specific extension, you can compile your C code as C and link it into your C++ program. You can't make the type with the flexible array member visible to your C++ code, but you can use it internally in the C code, and perhaps provide access to it in your C++ code via an opaque pointer. See the C++ FAQ for information about mixing C and C++ within the same program. (Or you can just use the g++ extension, at the cost of not being able to compile your code with other compilers.)
(I'm assuming that you're using g++. Some other compilers probably implement similar extensions.)
Upvotes: 19
Reputation: 2341
It's just ascii until such time as the compiler runs. So the preprocessor will paste the files together, then the compiler will treat the result as whatever language you specified.
It isn't a C flexible array member, it's a text file. Undefined behaviour remains.
Upvotes: -5
Reputation: 155455
An extern "C"
declaration only affects linkage of external functions, so that name mangling is not performed. It doesn't mean that the functions will be compiled using the rules of the C language instead of C++. In other words, including the code in some_random.cpp
will not make its behavior defined.
Upvotes: 10
Reputation: 63154
No.
extern "C"
is only a linkage specification, so that enclosed symbols can be linked to from C. It does not switch your compiler to "C mode" for a section of code.
Upvotes: 11