c ++使用数组作为成员初始化结构

时间:2010-04-16 03:21:30

标签: c++ struct initialization portability

再次编辑,因为我最初不清楚我是在编译时尝试初始化数组,而不是在运行时...


我有以下简化的测试用例:

typedef struct TestStruct
{
    int length;
    int values[];
};

TestStruct t = {3, {0, 1, 2}};
TestStruct t2 = {4, {0, 1, 2, 3}};

int main()
{
    return(0);
}

这适用于Visual C ++,但不能在linux下用g ++编译。任何人都可以帮助我使这种特定类型的初始化程序可移植吗?

其他细节:我正在使用的实际结构有几个其他int值,并且数组的长度范围可以从单个条目到超过1800个条目。

编辑:我认为(但不确定)这不是VLA问题。为了澄清,我正在尝试让编译器在编译时为我完成工作。运行时数组的长度是不变的。如果我错了,请道歉;我主要是一个c#/ Perl / Ruby程序员,他们一直在维护这个遗留应用程序......

任何帮助非常感谢。谢谢!

4 个答案:

答案 0 :(得分:24)

c ++没有与c99一样的最后一个元素的灵活数组成员。如果你不知道有多少元素,你应该使用std::vector,或者你应该指定多少元素。

编辑:您在编辑中已经说过数组是运行时常量,因此请指定大小,它应该可以正常工作。 g ++对以下代码没有问题:

struct TestStruct { // note typedef is not needed */
    int length;
    int values[3]; // specified the size
};

TestStruct t = {3, {0, 1, 2}};

int main() {
    // main implicitly returns 0 if none specified
}

编辑以解决您的评论,您可以使用以下模板:

template <int N>
struct TestStruct {
    int length;
    int values[N];
};

TestStruct<3> t3 = {3, {0, 1, 2}};
TestStruct<2> t2 = {2, {0, 1}};

int main() {}

唯一的问题是没有简单的方法将t2和t3放在一个容器中(比如list / vector / stack / queue / etc,因为它们有不同的大小。如果你想要,你应该使用{{ 1}}。另外,如果你这样做,那么没有必要存储大小(它与类型相关联。)所以你可以这样做:

std::vector

但是再一次,你不能轻易地将t2和t3放在一个“集合”中。

修改 总而言之,它听起来像你(除非你存储的数据多于一些数字和大小)根本不需要结构,并且不能只使用普通的旧向量。

template <int N>
struct TestStruct {
    static const int length = N;
    int values[N];
};

TestStruct<3> t3 = {{0, 1, 2}};
TestStruct<2> t2 = {{0, 1}};

int main() {}

这将允许您将t2和t3同时放在一个集合中。不幸的是typedef std::vector<int> TestStruct; int t2_init[] = { 0, 1, 2 }; TestStruct t3(t3_init, t3_init + 3); int t2_init[] = { 0, 1 }; TestStruct t2(t2_init, t2_init + 2); int main() {} (还)没有数组样式的初始化语法,所以我使用了一个快捷方式。但是编写一个函数以简单的方式填充向量非常简单。

编辑:好的,所以你不需要一个集合,但你需要将它传递给一个函数,你可以使用模板来保护类型安全!

std::vector

答案 1 :(得分:3)

GCC / Clang支持以下扩展


    typedef struct TestStruct
    {
        int length;
        int* values;
    };

    TestStruct t = {3, (int[]){0, 1, 2}};
    TestStruct t2 = {4, (int[]){0, 1, 2, 3}};

答案 2 :(得分:1)

struct TestStruct {
    int length;
    const int *values;
};

static const uint8_t TEST_STRUCT_VAL_1[] = {0, 1, 2};
const TestStruct t1 = {3, TEST_STRUCT_VAL_1};

static const uint8_t TEST_STRUCT_VAL_2[] = {0, 1, 2, 3};
const TestStruct t2 = {4, TEST_STRUCT_VAL_2};`

在我的例子中,使用gcc / g ++进行stm32编程,值数组只是原始数据存储,因此它是静态const,并且将存储在flash中。我用这种方式存储lcd显示的字体模式。

使用模板输入保存,但不保存大小。

答案 3 :(得分:0)

VLA仅在C99中受支持。 C ++不支持这一点。 从http://gcc.gnu.org/c99status.html开始,gcc现在支持VLA。