memset-elt-size编译错误的原因及解决方法咨询
关于memset触发
-Werror=memset-elt-size错误的原因与解决方法 问题场景
未在AutoMake Makefile中添加AM_CXXFLAGS += -Wno-memset-elt-size时,编译触发如下错误:
error: ‘memset’ used with length equal to number of elements without multiplication by element size [-Werror=memset-elt-size] memset (_floatOptions, 0, sizeof(_floatOptions));
触发错误的代码行:
memset (_floatOptions, 0, sizeof(_floatOptions));
相关代码片段:
class random_class { public: enum FloatOption { numFloatOptions }; /// Set a float option value /// @param f Float Option /// @param value value to be set void setFloatValue(FloatOption f, double value) { _floatOptions[f] = value; _isSetFloat[f] = true; } /// Return value of an float option /// @param f Float Option /// @return HostPlacement double getFloatValue(FloatOption f) const { return _floatOptions[f]; } private: double _floatOptions[numFloatOptions]; };
错误原因
- 编译器误判逻辑:这是GCC/Clang新增的警告(被
-Werror转为错误),用于检测开发者是否误将数组元素个数作为memset的第三个参数(要求是字节数)。你的代码中sizeof(_floatOptions)本身是正确的总字节数,但由于数组大小由枚举numFloatOptions定义,编译器误判你直接传递了元素个数而非字节数,触发警告。 - 空数组的潜在问题:枚举
numFloatOptions未显式赋值,默认值为0,导致_floatOptions是长度为0的空数组。空数组的memset操作无实际意义,进一步加剧了编译器的误判逻辑。
缓解方法
方法一:修正枚举定义(解决根源问题)
调整枚举,让numFloatOptions代表真实的选项数量,避免空数组:
enum FloatOption { // 先定义具体选项 OptionA, OptionB, // 最后用numFloatOptions统计总数 numFloatOptions };
此时数组长度为有效数值,编译器大概率不会再误判。
方法二:显式指定字节数计算方式
将sizeof(_floatOptions)替换为显式的元素个数乘单个元素字节数,消除编译器的误判依据:
memset(_floatOptions, 0, numFloatOptions * sizeof(double));
方法三:用C++原生初始化替代memset
在类构造函数中用C++初始化语法完成数组清零,完全避免memset调用:
class random_class { public: random_class() : _floatOptions{} {} // 列表初始化自动清零 // ... 其余代码不变 };
方法四:禁用该警告
如你所述,在AutoMake Makefile中添加编译选项关闭警告:
AM_CXXFLAGS += -Wno-memset-elt-size
内容的提问来源于stack exchange,提问作者user1584421
相关产品推荐
相关产品推荐

