How to initialize a struct using the c style while using the g++ compiler?
Asked Answered
M

4

6

Generally, in order to initialize a struct in c, we could only specify part of the fields. Like below:

static struct fuse_operations hello_oper = {
    .getattr    = hello_getattr,
    .readdir    = hello_readdir,
    .open       = hello_open,
    .read       = hello_read,
};

However, in C++, we should initialize the variables in the struct without naming the fields. Now, what if I would like to initialize a struct using the c style while using the g++ compiler, how to accomplish this? PS: the reason I need to do this is that the struct fuse_operations has too many fields in it.

Mouflon answered 25/8, 2012 at 13:7 Comment(0)
P
4

Unfortunately, even the C++11 version of the C++ standard lacks the designated initializers feature of C99.

Pettigrew answered 25/8, 2012 at 13:11 Comment(4)
@Glaudia You would need to put code in a C file, and compile it with a essentially a different compiler, even if it's from the same manufacturer. I would definitely avoid that.Pettigrew
so it's a bad practice in general ? because it is so widely usedGlaudia
@Glaudia Including C headers and linking with libraries that are built entirely in C is indeed used widely. Mixing C and C++ inside the same module, on the other hand, would be unusual.Pettigrew
@MimiEAM: extern "C" does not magically switch the compiler into C mode and does not somehow allow you to insert C code into C++ translation unit. extern "C" can only affect how C++ symbols are linked.Purgatory
T
5

You wrote:

   static struct fuse_operations hello_oper = {
       .getattr    = hello_getattr,
       .readdir    = hello_readdir,
       .open       = hello_open,
       .read       = hello_read,
   };

Generally, in order to initialize a struct in c, we could only specify part of the fields [...] However, in C++, we should initialize the variables in the struct without naming the fields. Now, what if I would like to initialize a struct using the c style while using the g++ compiler, how to accomplish this? PS: the reason I need to do this is that the struct fuse_operations has too many fields in it.

My solution was to specialize the struct with a constructor:

struct hello_fuse_operations:fuse_operations
{
    hello_fuse_operations ()
    {
        getattr    = hello_getattr;
        readdir    = hello_readdir;
        open       = hello_open;
        read       = hello_read;
    }
}

Then declare a static instance of the new struct:

static struct hello_fuse_operations hello_oper;

Testing worked OK for me (but this depends on the memory layout of the C-struct and C++-struct to be the same -- not sure that's guaranteed)

* UPDATE *

Though this approach worked fine in practice, I have subsequently converted my code to use a utility class, i.e., a class with a single static 'initialize' method that takes a reference to a fuse_operation struct and initializes it. This avoids any possible uncertainty regarding memory layout, and would be my recommended approach in general.

Truesdale answered 8/1, 2013 at 0:2 Comment(0)
P
4

Unfortunately, even the C++11 version of the C++ standard lacks the designated initializers feature of C99.

Pettigrew answered 25/8, 2012 at 13:11 Comment(4)
@Glaudia You would need to put code in a C file, and compile it with a essentially a different compiler, even if it's from the same manufacturer. I would definitely avoid that.Pettigrew
so it's a bad practice in general ? because it is so widely usedGlaudia
@Glaudia Including C headers and linking with libraries that are built entirely in C is indeed used widely. Mixing C and C++ inside the same module, on the other hand, would be unusual.Pettigrew
@MimiEAM: extern "C" does not magically switch the compiler into C mode and does not somehow allow you to insert C code into C++ translation unit. extern "C" can only affect how C++ symbols are linked.Purgatory
H
0

maybe you can write a variable param function which takes as input the function pointers and assigns the rest of the attribs as NULL. Since you only have one struct - fuse_operations, you can implement the function for only one struct. something like init_struct(int no_op, ...) wherein you pass function pointers to implementations. Its too complex and laborious, but I suppose you can write it once and use it always...

Heterochromatin answered 25/9, 2012 at 4:48 Comment(0)
V
0

With C++20, it has become possible to use C-style designated initializers.

Example:

struct S { int x; float y; };
 
S my_s{ .x = 1, .y = 2.3 };

See this on GodBolt.

Note that there are some finer points to keep in mind when using them, e.g. fallbacks for unspecified fields, the need to specify the fields in order of their appearance in the struct etc. Follow the link above for more information.

Vandervelde answered 24/3 at 9:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.