MSVC 中的复合文字

发布于 2024-09-26 03:07:29 字数 565 浏览 11 评论 0原文

在 GCC 中,我可以执行此操作:

(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 '{'

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

In GCC, I'm able to do this:

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

where:

struct CachedPath
{
    Ino ino;
};

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

MSVC gives the following error for these kind of casts:

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

How can I do this in MSVC? Further note that the code has been converted from C99, where I used designated initializers for this, and then cast it similarly. Any clarity on how these various features relate between C99, and MSVC/GCC implementations of C++ is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

抚笙 2024-10-03 03:07:29

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

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

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

The construct (Type){initialisers} is not a cast operation, but it is the syntactic construct of a compound literal.
This is a C99 construct, which GCC also supports in its C++ compiler as an extension. As far as I can determine, compound literals are not supported up to and including MSVC 2012, in either its C or C++ mode. The support in C mode was introduced later, in MSVC 2013. In C++ mode it is still not supported and I believe it is unlikely support will be added.

For MSVC 2012 and older, the alternatives for this construct are

  • Explicitly declare and initialise a temporary object of the desired struct type and use that instead of the compound literal in the assignment
  • Instead of doing a single assignment with the compound literal, use a separate assignment for each individual member.
残龙傲雪 2024-10-03 03:07:29

MSVC 不符合 C99,只是松散地符合以前版本的 C 标准。我不知道如何用 MSVC 实现您想要的语法,但是通过使用 static const 结构而不是匿名复合文字常量和本地 可以获得相同的效果>struct 使用正确值初始化的变量,而不是非常量的匿名复合文字。

这种方法背后的想法是,C99 复合文字(至少几乎)相当于相同范围内相同类型的局部变量,并使用大括号的内容进行初始化。在数据恒定的情况下使用 static const 结构只是一种优化(它可能会产生比 C99 复合文字方法更小/更快的代码)。

MSVC is not conformant to C99 and only loosely conformant to previous versions of the C standard. I know no way to do what you want syntactically with MSVC, but the same effect can be obtained by using static const structs instead of anonymous compound literal constants, and local struct variables that are initialized with the correct values instead of anonymous compound literals that are nonconstant.

The idea behind this approach is that a C99 compound literal is (at least nearly) equivalent to a local variable of the same type at the same scope, initialized with the contents of the braces. Using static const structs in the case where the data is constant is just an optimization (it will likely produce smaller/faster code than the C99 compound literal approach).

相权↑美人 2024-10-03 03:07:29

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]);
    }
}

Visual Studio, since VS2013, supports Compound literals and Designated initializers.
Which C99 features are available in the MS Visual Studio compiler?

Example:

// 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]);
    }
}
岁月染过的梦 2024-10-03 03:07:29

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)
    {
    }
};

MSVC is a mix of standards, and is not fully compliant with most of them, thus, you'll probably need to use a default initializer/constructor, like so (C++ way):

#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)
    {
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文