c++中的奇怪语法:return {.name=value,…}

Odd syntax in C++: return { .name=value, ... }

本文关键字:name value return 语法 c++      更新时间:2023-10-16

在阅读一篇文章时,我遇到了以下函数:

SolidColor::SolidColor(unsigned width, Pixel color)
  : _width(width),
    _color(color) {}
__attribute__((section(".ramcode")))
Rasterizer::RasterInfo SolidColor::rasterize(unsigned, Pixel *target) {
  *target = _color;
  return {
    .offset = 0,
    .length = 1,
    .stretch_cycles = (_width - 1) * 4,
    .repeat_lines = 1000,
  };
}

作者用return语句做了什么?我以前没有见过这样的东西,我不知道如何寻找它……它对纯C也有效吗?

编辑:链接到原文

这在c++中是无效的。

它(在某种程度上)使用了C语言中被称为"复合字面量"answers"指定初始化器"的两个特性,一些c++编译器将其作为扩展支持。"sort of"来自这样一个事实:要成为一个合法的C复合字面量,它应该具有看起来像强制转换的语法,所以你会有这样的东西:

return (RasterInfo) {
    .offset = 0,
    .length = 1,
    .stretch_cycles = (_width - 1) * 4,
    .repeat_lines = 1000,
  };
但是,不管语法上的差异如何,它基本上是创建了一个临时结构体,其成员按块中指定的方式初始化,因此这大致相当于:
// A possible definition of RasterInfo 
// (but the real one might have more members or different order).
struct RasterInfo {
    int offset;
    int length;
    int stretch_cycles;
    int repeat_lines;
};
RasterInfo rasterize(unsigned, Pixel *target) { 
    *target = color;
    RasterInfo r { 0, 1, (_width-1)*4, 1000};
    return r;
}
最大的区别(如你所见)是指定初始化器允许你使用成员名来指定哪个初始化器指向哪个成员,而不是仅仅依赖于顺序/位置。

这是一个C99复合文字。这个特性是C99特有的,但是gcc和clang也选择在c++中实现它(作为扩展)。

6.26复合字面值

ISO C99支持复合文字。复合字面值看起来像A包含初始化式的强制转换。它的值是该类型的对象类型中指定的元素初始化;它是一个左值。作为扩展,GCC支持复合字面量在C90模式和c++中,尽管语义有些不同