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

此生再无相见时 提交于 2019-12-22 03:24:33

问题


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?


回答1:


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.)




回答2:


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.




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/31881811/does-extern-c-with-c-avoid-undefined-behavior-that-is-legal-in-c-but-not-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!