如何在使用g++编译器时使用C语言风格初始化结构体?

6

通常,为了在C语言中初始化一个struct,我们只能指定部分字段。如下所示:

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

然而,C++中我们应该在struct中初始化变量时不命名字段。 那么,如果我想使用C风格来初始化一个struct并使用g++编译器,该如何完成呢?PS: 我需要这样做的原因是struct fuse_operations中有太多的字段。

3个回答

5
你写道:
   static struct fuse_operations hello_oper = {
       .getattr    = hello_getattr,
       .readdir    = hello_readdir,
       .open       = hello_open,
       .read       = hello_read,
   };

通常,在c语言中初始化结构体时,我们只能指定部分字段[...]然而,在C ++中,我们应该在不命名字段的情况下初始化结构体变量。那么,如果我想使用c风格初始化结构体,同时使用g ++编译器,该如何实现呢?PS:我需要这样做的原因是结构体fuse_operations中有太多的字段。

我的解决方案是使用构造函数对结构体进行特化:

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

然后声明一个新结构体的静态实例:
static struct hello_fuse_operations hello_oper;

对我来说,测试工作正常(但这取决于C结构体和C++结构体的内存布局是否相同--不确定是否有保证)

* 更新 *

虽然这种方法在实践中运行良好,但我随后将我的代码转换为使用实用程序类,即具有单个静态“initialize”方法的类,该方法接受对fuse_operation结构的引用并对其进行初始化。这避免了任何可能的关于内存布局的不确定性,并且通常是我推荐的方法。


3

@MimiEAM,您需要将代码放入C文件中,并使用基本上不同的编译器进行编译,即使它来自同一制造商。我肯定会避免这种情况。 - Sergey Kalinichenko
那么这是一种普遍的不良做法吗?因为它被广泛使用。 - MimiEAM
1
@MimiEAM 包含 C 头文件并链接完全由 C 构建的库确实被广泛使用。另一方面,在同一模块中混合使用 C 和 C++ 则是不寻常的。 - Sergey Kalinichenko
1
@MimiEAM: extern "C"并不能神奇地将编译器切换到C模式,也不能以某种方式允许您将C代码插入到C++翻译单元中。extern "C"只能影响C++符号的链接方式。 - AnT stands with Russia

0
也许你可以编写一个可变参数函数,该函数以函数指针作为输入并将其余属性分配为NULL。由于您只有一个结构体 - fuse_operations,因此您可以仅为一个结构体实现该函数。类似于init_struct(int no_op,...),其中您传递函数指针以进行实现。这太复杂和费力了,但我想你可以编写它一次并始终使用它...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接