MSVC 中的复合文字[重复]

问题描述 投票:0回答:4

在海湾合作委员会,我能够做到这一点:

(CachedPath){ino}
inode->data = (struct Data)DATA_INIT;

地点:

struct CachedPath
{
    Ino ino;
};

typedef int8_t Depth;
struct Data
{
    Offset size;
    Blkno root;
    Depth depth;
};
#define DATA_INIT {0, -1, 0}

MSVC 对于此类类型转换给出以下错误:

error C2143: syntax error : missing ';' before '{'

如何在 MSVC 中执行此操作? 进一步注意,代码已从 C99 转换而来,其中我为此使用了指定的初始值设定项,然后进行类似的转换。如果能清楚地了解 C99 和 C++ 的 MSVC/GCC 实现之间的这些不同功能之间的关系,我们将不胜感激。

c++ c visual-studio-2010 gcc compound-literals
4个回答
14
投票

构造

(Type){initialisers}
不是强制转换操作,而是复合文字的语法构造。 这是一个 C99 构造,GCC 在其 C++ 编译器中也支持它作为扩展。据我所知,在 MSVC 2012 及之前版本,无论是 C 模式还是 C++ 模式,都不支持复合文字。 C 模式的支持是后来在 MSVC 2013 中引入的。在 C++ 模式下仍然不支持,我相信不太可能会添加支持。

对于 MSVC 2012 及更早版本,此构造的替代方案是

  • 显式声明并初始化所需结构类型的临时对象,并在赋值中使用它而不是复合文字
  • 不要对复合文字进行单一赋值,而是对每个单独的成员使用单独的赋值。

3
投票

MSVC 不符合 C99,仅松散地符合以前版本的 C 标准。我不知道如何用 MSVC 在语法上做你想要的事情,但是通过使用

static const
结构而不是匿名复合文字常量,以及使用正确值而不是初始化的本地
struct
变量可以获得相同的效果非常量的匿名复合文字。

这种方法背后的想法是,C99 复合文字(至少几乎)相当于相同范围内相同类型的局部变量,并使用大括号的内容进行初始化。在数据恒定的情况下使用

static const
结构只是一种优化(它可能会产生比 C99 复合文字方法更小/更快的代码)。


2
投票

Visual Studio 自 VS2013 起支持复合文字和指定初始值设定项。 MS Visual Studio 编译器提供哪些 C99 功能?

示例:

// main.c
#include <stdio.h>

void func(int(*array)[3]);

int main()
{
    // Designated initializers

    int a[6] = { [4] = 29, [2] = 15 }; // [0, 0, 15, 0, 29, 0]

    struct point { int x, y; };
    struct point p = { .y = 13, .x = 27 }; // x = 27, y = 13

    union foo { int i; double d; };
    union foo f = { .d = 4 }; // d = 4.0

    struct point ptarray[5] = { [2].y = 34, [2].x = 42, [0].x = 58 };
    // (58 0), (0 0), (42 34), (0 0), (0 0)

    // Compound literals

    int *a1 = NULL;
    a1 = (int[6]) { [4] = 29, [2] = 15 }; // [0, 0, 15, 0, 29, 0]

    struct point p1;
    p1 = (struct point) { .y = 13, .x = 27 }; // x = 27, y = 13

    union foo f1;
    f1 = (union foo) { .d = 4 }; // d = 4.0

    struct point *ptarray1 = NULL;
    ptarray1 = (struct point[5]) { [2].y = 34, [2].x = 42, [0].x = 58 };
    // (58 0), (0 0), (42 34), (0 0), (0 0)

    int *p2 = NULL;
    p2 = (int[2]) { -1 };
    p2 = (int[]) { -73, 89, 92 };
    func(&(int[]) { -73, 89, 92 });

    return 0;
}

void func(int(*array)[3])
{
    for (int i = 0; i < 3; i++) {
        printf("%d ", (*array)[i]);
    }
}

0
投票

MSVC 是多种标准的混合体,并不完全符合其中的大多数标准,因此,您可能需要使用默认的初始化程序/构造函数,如下所示(C++ 方式):

#define DATA_INIT 0,-1,0
inode->data = Data(DATA_INIT);

struct Data
{
    Offset size;
    Blkno root;
    Depth depth;

    Data(Offset size, Blkno root, Depth depth) : size(size), root(root), depth(depth)
    {
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.