【问题标题】:Designated Initializers in C99: How to handle empty uninitialized struct members in C11?C99 中的指定初始化程序:如何处理 C11 中未初始化的空结构成员?
【发布时间】:2013-05-29 14:16:42
【问题描述】:

因为在 C 中我可以按名称调用结构的成员 (myStruct.myMember = ),所以我想知道在 C++ 中我将如何处理那些未初始化的成员。 据我了解,C++ 不支持这种初始化:

static struct usb_endpoint_descriptor  fs_source_desc = {
        .bLength =      USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =  USB_DT_ENDPOINT,
        .bmAttributes =     USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =   __constant_cpu_to_le16 (64),
    };

但是当我使用正确的语法时,如何处理未初始化的成员? 假设我想要 bDescriptorType 未初始化。我是否将其设置为 NULL?

static struct usb_endpoint_descriptor fs_source_desc = {
    USB_DT_ENDPOINT_SIZE,
        NULL,
        USB_ENDPOINT_XFER_BULK,
        __constant_cpu_to_le16 (64)
};

或者在 C++ 中有什么方法可以通过名称初始化结构的成员?

【问题讨论】:

  • 这是一个非常愚蠢的问题标题。既然您已经知道您正在谈论的 C 语言功能不是 C++ 的功能,那么您为什么不能给这篇文章起一个比在编写无效代码时打印随机错误更明智的标题?

标签: c++ c c99


【解决方案1】:

如何处理未初始化的成员?

您描述的功能称为指定初始化程序,是在 C99 中引入的。 C++ 不支持它。所有未显式初始化的成员都保证设置为零 (*)。

也许您没有考虑到它,但同样适用于常规结构初始化。示例:

typedef struct
{
  int a;
  int b;
} ab;

ab mystruct = { .a = 1 }; // a is 1, b is guaranteed to be 0
ab mystruct = { 1 };      // a is 1, b is guaranteed to be 0    

(最后一个例子也适用于 C++。)

这个语言规则是我们可以通过键入将结构/数组中的所有元素初始化为零的原因:

ab mystruct = { 0 };

因为它实际上意味着“将a 设置为零,然后让所有其他元素隐式初始化为零”。


(*) 形式上,它们被初始化为好像它们具有静态存储持续时间,即数据设置为零,指针设置为 NULL 等。C11 6.7.9/10。

【讨论】:

  • 非常感谢!现在我可以相应地表达标题以及我的源代码!。
【解决方案2】:

如果您使用C++,则使用构造函数。 NULL 的初始化确实更像 C 方式。

不,没有标准的 C++ 方法来使用命名参数(boost::parameters 之类的东西可能会有所帮助,但这里没有必要)。

你的情况可能是这样的

struct usb_endpoint_descriptor
{
   usb_endpoint_desctiptor(type bL, type bAttr, type wSize) :
   bLength(bL), bAttributes(bAttr), wMaxPacketSize(wSize) {}
   type bLength;
   type bDescriptorType;
   type bmAttributes;
   type wMaxPacketSize;
};

但是,在 C++ 中保留未初始化的变量是一种不好的风格。

所以,如果你使用C结构,你可以

1) 编写 C++ 包装器。

2) 编写派生类。

3) 初始化字段,你不想用一些默认值初始化。

【讨论】:

  • 谢谢!我使用的结构来自 /usb/ch9.h 头文件。所以没有可用的构造函数。
  • @tzippy 在 C 中,如果您为任何成员提供显式初始化程序,则未给出显式初始化程序的成员将被初始化,就好像它们是静态存储持续时间的对象一样,这意味着使用类型-适当的值 0。
  • 这种情绪,总是更喜欢 C++ 中的构造函数,但在 c++17 和 c++20 中不再正确。对聚合初始化有更多支持,我们鼓励这样做。
【解决方案3】:

仅供参考,之前的所有答案都是正确的。 C++ 中不支持指定的初始化程序...直到 C++20。

C++20 在该版本的 C++ 标准中添加了聚合初始值设定项。 语法不同于 C99 点表示法,因为我猜标准委员会希望语法更符合 Cplusplussesque 的习惯。

这是一个关于堆栈溢出的问题 Designated initializers in C++20

这是一个受欢迎的参考网站。 https://en.cppreference.com/w/cpp/language/aggregate_initialization

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 2011-05-11
    相关资源
    最近更新 更多