gcc-8 Wstringop-截断
gcc-8 Wstringop-truncation
我正在尝试修复一些 C 代码,其中 gcc-8 抱怨 Wstringop-truncation(代码是 here)
在我无法控制的服务器上编译该代码时,既不能添加 pragma 语句,也不能禁用 Wstringop-truncation 诊断,我收到的警告是:
gcc-8 -I"/home/hornik/tmp/R/include" -DNDEBUG -I./cqdb/include -I./crf/src -I./liblbfgs/include -I./include -I"/home/hornik/lib/R/Library/3.6/x86_64-linux-gnu/Rcpp/include" -I/usr/local/include -fpic -g -O2 -Wall -pedantic -mtune=native -c cqdb/src/cqdb.c -o cqdb/src/cqdb.o
cqdb/src/cqdb.c: In function ‘cqdb_writer_close’:
cqdb/src/cqdb.c:270:5: warning: ‘strncpy’ output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation]
strncpy((char*)header.chunkid, CHUNKID, 4);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cqdb/src/cqdb.c: In function ‘cqdb_reader’:
cqdb/src/cqdb.c:469:9: warning: ‘strncpy’ specified bound 4 equals destination size [-Wstringop-truncation]
strncpy((char*)db->header.chunkid, (const char*)p, 4);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我想重写 strncpy 语句以删除这些警告。我是否正确,我需要在以下几行中替换
strncpy((char*)header.chunkid, CHUNKID, 4);
with strncpy((char*)header.chunkid, CHUNKID, 5);
and strncpy((char*)db->header.chunkid, (const char*)p, 4);
with strncpy((char*)db->header.chunkid, (const char*)p, 5);
下面是cqdb.c中的相关代码。它主要检查文件的类型是否为 'CQDB'。
请注意,虽然我真的很想访问,但我无法访问这台机器,所以我无法测试 C 代码的修复是否有效。
#define CHUNKID "CQDB"
typedef struct {
int8_t chunkid[4]; /**< Chunk identifier, "CQDB". */
uint32_t size; /**< Chunk size including this header. */
uint32_t flag; /**< Global flags. */
uint32_t byteorder; /**< Byte-order indicator. */
uint32_t bwd_size; /**< Number of elements in the backward array. */
uint32_t bwd_offset; /**< Offset to the backward array. */
} header_t;
int cqdb_writer_close(cqdb_writer_t* dbw)
{
header_t header;
strncpy((char*)header.chunkid, CHUNKID, 4);
...
}
cqdb_t* cqdb_reader(const void *buffer, size_t size)
{
cqdb_t* db = NULL;
/* Check the file chunkid. */
if (memcmp(buffer, CHUNKID, 4) != 0) {
return NULL;
}
db = (cqdb_t*)calloc(1, sizeof(cqdb_t));
const uint8_t* p = NULL;
db->buffer = buffer;
p = db->buffer;
strncpy((char*)db->header.chunkid, (const char*)p, 4);
...
}
问题中strncpy
的用法实际上是正确的(左对齐缓冲区中的一些字符,右填充空字节),但警告是因为这个函数经常被尝试的人误用复制以 null 结尾的字符串。
对于问题中显示的代码,我会将 strncpy
调用替换为:
set_chunkid(&header);
添加新函数的位置:
void set_chunkid(header_t *hdr)
{
_Static_assert(sizeof CHUNKID == sizeof hdr->chunkid + 1, "chunk ID not 4 chars");
memcpy(&hdr->chunkid, CHUNKID, sizeof hdr->chunkid);
}
如果此函数未涵盖其他用例,请更新问题。
我正在尝试修复一些 C 代码,其中 gcc-8 抱怨 Wstringop-truncation(代码是 here)
在我无法控制的服务器上编译该代码时,既不能添加 pragma 语句,也不能禁用 Wstringop-truncation 诊断,我收到的警告是:
gcc-8 -I"/home/hornik/tmp/R/include" -DNDEBUG -I./cqdb/include -I./crf/src -I./liblbfgs/include -I./include -I"/home/hornik/lib/R/Library/3.6/x86_64-linux-gnu/Rcpp/include" -I/usr/local/include -fpic -g -O2 -Wall -pedantic -mtune=native -c cqdb/src/cqdb.c -o cqdb/src/cqdb.o
cqdb/src/cqdb.c: In function ‘cqdb_writer_close’:
cqdb/src/cqdb.c:270:5: warning: ‘strncpy’ output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation]
strncpy((char*)header.chunkid, CHUNKID, 4);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cqdb/src/cqdb.c: In function ‘cqdb_reader’:
cqdb/src/cqdb.c:469:9: warning: ‘strncpy’ specified bound 4 equals destination size [-Wstringop-truncation]
strncpy((char*)db->header.chunkid, (const char*)p, 4);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我想重写 strncpy 语句以删除这些警告。我是否正确,我需要在以下几行中替换
strncpy((char*)header.chunkid, CHUNKID, 4);
with strncpy((char*)header.chunkid, CHUNKID, 5);
and strncpy((char*)db->header.chunkid, (const char*)p, 4);
with strncpy((char*)db->header.chunkid, (const char*)p, 5);
下面是cqdb.c中的相关代码。它主要检查文件的类型是否为 'CQDB'。 请注意,虽然我真的很想访问,但我无法访问这台机器,所以我无法测试 C 代码的修复是否有效。
#define CHUNKID "CQDB"
typedef struct {
int8_t chunkid[4]; /**< Chunk identifier, "CQDB". */
uint32_t size; /**< Chunk size including this header. */
uint32_t flag; /**< Global flags. */
uint32_t byteorder; /**< Byte-order indicator. */
uint32_t bwd_size; /**< Number of elements in the backward array. */
uint32_t bwd_offset; /**< Offset to the backward array. */
} header_t;
int cqdb_writer_close(cqdb_writer_t* dbw)
{
header_t header;
strncpy((char*)header.chunkid, CHUNKID, 4);
...
}
cqdb_t* cqdb_reader(const void *buffer, size_t size)
{
cqdb_t* db = NULL;
/* Check the file chunkid. */
if (memcmp(buffer, CHUNKID, 4) != 0) {
return NULL;
}
db = (cqdb_t*)calloc(1, sizeof(cqdb_t));
const uint8_t* p = NULL;
db->buffer = buffer;
p = db->buffer;
strncpy((char*)db->header.chunkid, (const char*)p, 4);
...
}
问题中strncpy
的用法实际上是正确的(左对齐缓冲区中的一些字符,右填充空字节),但警告是因为这个函数经常被尝试的人误用复制以 null 结尾的字符串。
对于问题中显示的代码,我会将 strncpy
调用替换为:
set_chunkid(&header);
添加新函数的位置:
void set_chunkid(header_t *hdr)
{
_Static_assert(sizeof CHUNKID == sizeof hdr->chunkid + 1, "chunk ID not 4 chars");
memcpy(&hdr->chunkid, CHUNKID, sizeof hdr->chunkid);
}
如果此函数未涵盖其他用例,请更新问题。