简体   繁体   中英

Static struct initialization without designated initializers?

The following designated initializer example is valid in Visual Studio 2019 with /std:c++latest, but I'm wondering how to accomplish the same thing without designated initializers in Visual Studio 2017.

I am using C++ and I realize there is an object-oriented way to do this but I am NOT asking how to recreate this in C++ using constructors. This makes the tagging for this question a bit messy, sorry for any confusion.

I'm also struggling with the terminology here. Just to confirm, is &(struct Foo) a compound literal? And this is achieving compile time static initialization? Could constexpr be used somehow here instead?

// Header
struct Foo
{
    void (*Bar)();
};

extern struct Foo *FooAPI;

// Source
static void Bar()
{

}

static struct Foo *FooAPI = &(struct Foo) { // Error: Expecting an expression
    .Bar = Bar
};
 struct Foo { void *(Bar)(); };

Foo::Bar is a member function that returns void* . C doesn't have member functions, so this would be ill-formed in C.

 {.Bar = Bar; }

This is ill-formed in both languages. You may not put semicolon there. Solution: Remove the semicolon. Optionally replace with a comma.

Besides, Foo::Bar is a member function so you cannot provide an initialiser for it. You may have intended Foo::Bar to be a pointer to function that returns void . The syntax for that would be:

struct Foo
{
    void (*Bar)();
};
// or nicer way:
struct Foo
{
    using Fun = void();
    Fun* Bar;
};
 extern struct Foo *FooAPI; static struct Foo *FooAPI =

A variable that was declared extern may not be redeclared static . Solution: Remove static .

Just to confirm, is &(struct Foo) a compound literal?

(struct Foo) {... } is a compound literal. The unary & is the addressof operator and the compound literal is the operand in this case.

Static struct initialization without designated initializers?

Simply remove the designator so that initialisers apply to members in their declaration order. If the initialisers were not in the declaration order of members, then the initialisers must be re-ordered. In your case:

{
    .Bar = Bar,
}
// becomes ->
{
    /*.Bar =*/ Bar,
}

I am using C++

There are no compound literals in C++. They are a C feature (since C99).

To rewrite it in C++, you need to use a named variable:

static Foo foo {
    Bar,
};
Foo *FooAPI = &foo;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM