Yannick
Yannick

Reputation: 862

C++ struct with methods, C declaration without methods

I already highly suspect it's doable and not risky at all but I still want to know for sure, so here's my thing...

I have a C++ code that use quite big structs (15-30 fields) as containers, as arguments for the constructor of a class. The thing with those structs is that I need to declare them using the C99 syntax (incompatible with C++ ffs):

FooBar fb = { .foo = 12, .bar = 3.4 };

Because it's unthinkable for me to have a constructor, since some fields can be safely skipped while initializing those structs, while others are not, etc. (they are only and exclusively initialized by "user supplied" data, user is me in the occurence), a bit like if they described a configuration.

Anyways, point made, I'm down to using one .h header that declares the struct using plain C syntax, and one .c file containing the structs I initialize, and THEN I make them accessible in my .cpp files using extern "C". It works well... except I would find very handy to be able to have methods for those structs.

So my question is, is it possible to a declare struct like so

#ifdef __cplusplus
    // C++ compatible declarations with methods
    struct foobar {
        int foo;
        float bar;

        int method1();
        int method2();
        void method3();
        [etc.]
    };
#else
    /* C compatible declarations, no methods */
    struct foobar {
        int foo;
        float bar;
    };
#endif

This way I could use in C++ some methods bound to the structs (its more elegant, OOP oriented), and I could safely initialize them in my C code using C99's designated initializers.

What I fear is some potentially unknown-by-me issues that could end up making the struct offets different in the C code than in the C++ code. Do those issues exist, or not?

Thanks

Upvotes: 0

Views: 716

Answers (1)

nneonneo
nneonneo

Reputation: 179422

In C++11, if your struct is standard-layout, then it has the same layout as an equivalent C struct. The rules for what constitutes a standard-layout structure are as follows:

A standard-layout class is a class that:

— has no non-static data members of type non-standard-layout class (or array of such types) or reference,

— has no virtual functions (10.3) and no virtual base classes (10.1),

— has the same access control (Clause 11) for all non-static data members,

— has no non-standard-layout base classes,

— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and

— has no base classes of the same type as the first non-static data member.

Since your structure only has a few public data members, and a few non-virtual methods, your structure is standard-layout. You could express it with less duplication as

struct foobar {
    int foo;
    float bar;
#ifdef __cplusplus
    int method1();
    int method2();
    void method3();
#endif
};

In prior versions of C++, your type would have to be a plain-old-data (POD) type, and there are some more restrictions. However, your struct would still be POD (no virtual functions, no constructors or destructors, no base class), so it would still be layout-compatible with C.

Upvotes: 1

Related Questions