所以有这个 gcc 警告让我感到困扰:
warning: assuming signed overflow does not occur when simplifying multiplication
它指向的代码如下所示:
/* Move the memory block of entries after the removed one - if any. */
if (database->entries + database->entries_size - 1 != database_entry) {
memmove(
database_entry,
database_entry + 1,
sizeof(spm_database_entry_t)
* (
(database->entries + database->entries_size)
- database_entry - 1
)
);
}
您可以很容易地猜到,它会在元素移除后移动容器的部分内存,以允许其进一步重新分配(缩小)。
database_entry
是指向spm_database_entry_t*
已移除元素的类型指针database->entries
是指向数组的指针spm_database_entry_t
database->entries_size
是移除前size_t
的代表数字database->entries
元素
如何摆脱警告?我可以防止乘法简化还是有更好的方法来计算需要移动多少内存?
编辑
你确定database_entry < database->entries + database->entries_size
吗?
积极的。
您使用的编译器标志是什么?
-Wall -Wextra -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes
-Wmissing-prototypes -Wdeclaration-after-statement -Wwrite-strings
-Winit-self -Wcast-align -Wstrict-aliasing=2 -Wformat=2
-Wmissing-declarations -Wmissing-include-dirs -Wno-unused-parameter
-Wuninitialized -Wold-style-definition -Wno-missing-braces
-Wno-missing-field-initializers -Wswitch-default -Wswitch-enum
-Wbad-function-cast -Wstrict-overflow=5 -Winline -Wundef -Wnested-externs
-Wunreachable-code -Wfloat-equal -Wredundant-decls
-pedantic -ansi
-fno-omit-frame-pointer -ffloat-store -fno-common -fstrict-aliasing
编辑2
在乘法unsigned int
之前强制转换似乎可以解决问题,但强制转换size_t
不会。我不明白-标准说size_t
总是未签名...
编辑3
如果上下文可以有任何用途:https ://github.com/msiedlarek/libspm/blob/master/libspm/database.c#L116
编辑4
基于史蒂夫哈的回答的解决方案:
/* Calculate how meny entries need moving after the removal. */
size_t entries_to_move = (
(database->entries + database->entries_size)
- database_entry - 1
);
/* Move the memory block of entries after the removed one - if any. */
memmove(
database_entry,
database_entry + 1,
sizeof(spm_database_entry_t) * entries_to_move
);