How to define an extern, C struct returning function in C++ using MSVC? -
the following source file not compile msvc compiler (v15.00.30729.01):
/* stest.c */ #ifdef __cplusplus extern "c" { #endif struct test; /* nb: may extern when imported module. */ struct test make_test(int x); struct test { int x; }; struct test make_test(int x) { struct test r; r.x = x; return r; } #ifdef __cplusplus } #endif
compiling cl /c /tpstest.c
produces following error:
stest.c(8) : error c2526: 'make_test' : c linkage function cannot return c++ class 'test' stest.c(6) : see declaration of 'test'
compiling without /tp
(which tells cl
treat file c++) works fine. file compiles fine in digitalmars c , gcc (from mingw) in both c , c++ modes. used -ansi -pedantic -wall
gcc , had no complaints.
for reasons go below, need compile file c++ msvc (not others), functions being compiled c. in essence, want normal c compiler... except 6 lines. there switch or attribute or can add allow work?
the code in question (though not above; that's reduced example) being produced code generator.
as part of this, need able generate floating point nans , infinities constants (long story), meaning have compile msvc in c++ mode in order this. found 1 solution works, , only works in c++ mode.
we're wrapping code in extern "c" {...}
because want control mangling , calling convention can interface existing c code. ... because trust c++ compilers far throw smallish department store. tried wrapping just reinterpret_cast
line in extern "c++" {...}
, of course doesn't work. pity.
there potential solution found requires reordering declarations such full struct definition comes before function foward decl., inconvenient due way codegen performed, i'd really avoid having go down road if can.
this interesting question. say, compiling code c code rightly produces no error. , msvc seems have trouble when compiled c++ code.
since other c++ compilers don't have problem code, might bug in msvc, can see how msvc might have rationale error. when c++ compiler hits line:
struct test;
that's incomplete declaration of struct test
- compiler doesn't know if complete definition of struct test
contain c++ specific items (virtual functions, inheritance, etc). note types in extern "c"
block can still use c++ facilities; extern "c"
language linkage specification applies "function types of function declarators, function names, , variable names introduced declaration(s)" (7.5/4 "linkage specifications").
so see how when msvc's c++ compiler comes across extern "c"
function that's returning incomplete type, might decide needs return error @ point in case type turns out not plain c-style pod type.
the c++ standard (7.5/9 "linkage specifications"):
linkage c++ objects defined in other languages , objects defined in c++ other languages implementation-defined , language-dependent. object layout strategies of 2 language implementations similar enough can such linkage achieved.
so msvc might have leeway (standards-wise) if has reason not permit extern "c"
functions returning non-pod objects, though i'm not sure why msvc have problem when other windows compilers don't. if knows details (or if know i'm plain off-base here), i'd appreciate note.
not of this helps - it's guess @ rationale.
without knowing more codegen process , how might able influence it, i'm not sure decent options might have - maybe post-processing of generated files split out stuff needs compiled c (or rearranges declarations). can imagine that might nightmare working , maintain.
Comments
Post a Comment