Glenn Teitelbaum
Glenn Teitelbaum

Reputation: 10343

Does extern C with C++ avoid undefined behavior that is legal in C but not C++?

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

Answers (4)

Keith Thompson
Keith Thompson

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

Jon Chesterfield
Jon Chesterfield

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

user4815162342
user4815162342

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

Quentin
Quentin

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

Related Questions