SUSE环境下GCC 4.8编译报错:数组被用作初始化器
嘿,我来帮你拆解这个在SUSE上用GCC 4.8编译时碰到的错误!先给你理清楚为啥会出这个问题,再给你几个靠谱的解决方向。
为啥会出现这个错误?
GCC 4.8算是比较老的编译器了,对C标准的支持(尤其是C11及之后的特性)不如新版本灵活,而且对数组初始化的规则卡得比较严。这个错误通常出现在这几种情况:
- 你试图直接用一个数组去初始化另一个数组,比如写了
int arr[] = {1,2,3}; int arr2[] = arr;——这在C++03(GCC4.8默认标准)里是绝对不允许的,数组没法直接拷贝初始化。 - 你的SmoQuery构造函数里,要么参数本身是数组类型,要么在初始化类成员的时候,想用数组直接给另一个数组成员赋值,GCC4.8不认这种写法。
- 要是代码里用了C++11的统一初始化(
{}语法),GCC4.8对这部分的支持有局限性,也可能误判成非法的数组初始化器。
结合你给的SmoQuery构造函数代码,大概率是构造函数的参数涉及数组类型,或者在初始化列表里碰了数组直接初始化的禁区。
怎么解决?
给你几个实用的方案,按推荐程度排序:
1. 把数组换成标准容器(首推!)
如果你的logicalNameList_t这类类型是数组的typedef,直接换成std::vector或者std::array就完事了——这俩是C++标准容器,支持直接拷贝,完全避开数组的初始化限制:
// 举个例子,把数组类型改成std::vector typedef std::vector<std::string> logicalNameList_t; // 然后构造函数的参数也跟着调整成引用,传递和初始化都没问题 SmoQuery(SqlLogonElem * const & eLogon, optionsInfo_t * const & optionsInfoP, logicalNameList_t const& pRequestedDbList, logicalNameList_t const& pExcludeDbList, SqlDatabaseElem * const & peDatabase, dsBool_t const bIncludeFrontEndCapacity, ...)
2. 手动拷贝数组内容(必须保留数组时用)
要是实在不能改数组类型,那就别直接用数组当初始化器,手动把元素拷过去就行。可以用循环,或者更简洁的std::copy(记得加<algorithm>头文件):
// 假设类里有个数组成员m_requestedDbList SmoQuery(...) : /* 这里放其他成员的初始化 */ { // 用std::copy把参数数组的内容拷到成员数组里 std::copy(std::begin(pRequestedDbList), std::end(pRequestedDbList), std::begin(m_requestedDbList)); }
要是你用的是变长数组(VLA,GCC4.8支持但属于扩展特性),std::begin/end可能不好使,那就自己写循环,用数组长度控制次数就行。
3. 开C++11编译选项
GCC4.8默认用的是C03标准,要是你代码里用了C11的初始化特性,得手动加编译选项告诉编译器:
g++ -std=c++11 你的代码文件.cpp -o 生成的程序名
开了C++11支持后,GCC4.8会兼容更多新特性,说不定就能解决这个初始化错误。
4. 检查构造函数的参数匹配
最后再确认下:构造函数的参数类型和你传的实参是不是匹配?比如参数是指针,但你传了多维数组名;或者参数是数组,你传了指针——这种类型不匹配也可能触发这个错误。
小提示
要是还是找不到具体哪行错了,把编译错误的完整信息(包括行号)贴出来,能更快定位问题。不过按上面的方法,大部分情况都能搞定啦!
内容的提问来源于stack exchange,提问作者TonyI

