C++ Lint:调用函数';memcpy(void*、const void*、std::size_t)和x27;违反语义';(3n>;4)和#x27;

C++ Lint:调用函数';memcpy(void*、const void*、std::size_t)和x27;违反语义';(3n>;4)和#x27;,c++,lint,C++,Lint,这是我代码库的一部分。 我不明白警告的意思,所以我无法解决这个问题。。。 代码: 第1、2和3行的该逻辑的LINT warning 426为 Call to function 'memcpy(void *, const void *, std::size_t)' violates semantic '(3n>4)' 您能告诉我它的确切含义吗?…(3n>4)表示用于调用memcpy()的第三个参数应该大于4,并且您的调用违反了此语义。语义似乎表明memcpy()不应用于复制小于机器字(通常

这是我代码库的一部分。 我不明白警告的意思,所以我无法解决这个问题。。。 代码:

第1、2和3行的该逻辑的LINT warning 426为

Call to function 'memcpy(void *, const void *, std::size_t)' violates semantic '(3n>4)'
您能告诉我它的确切含义吗?…

(3n>4)
表示用于调用
memcpy()
的第三个参数应该大于4,并且您的调用违反了此语义。语义似乎表明
memcpy()
不应用于复制小于机器字(通常为4)的数据。这就是林特警告你的原因。语义是否恰当是另一个问题


以下是lint警告426的说明:

426对函数“Symbol”的调用违反了语义“String”——当违反了用户语义(由-sem定义)时,会发出此警告消息String'是被违反的语义的子部分。例如:

结果显示在消息中:

Call to function 'f(int, int)' violates semantic '(1n>10)'
因此,您环境中的
memcpy()
可能具有如下主要lint语义:

// lint -sem(memcpy, 3n > 4)
void* memcpy(void* s1, const void* s2, std::size_t n);

就您的情况而言,如果您想要实现的是:

memcpy(&Record.Colours01[0], &diagData[0], 4); //Line 1
memcpy(&Record.Colours02[1], &diagData[4], 4); //Line 2
memcpy(&Record.Colours03[2], &diagData[8], 4); //Line 3
然后简单地说:

memcpy(&Record, diagData, sizeof(Record));  

将在不触发lint警告的情况下完成所有工作。

lint告诉您不应该调用
memcpy
4个或更少的字节

这太愚蠢了

现代编译器知道memcpy是什么。如果在GCC或Clang上进行优化编译,至少会发现在x86上,在生成的代码中,4字节的
memcpy
已被单个
mov
所取代。(从内存复制到内存时,可能有两个
mov
s。)

您编写这段代码的方式是唯一可移植的、安全的方式,除了逐个编写字节副本之外。特别是,编写此代码是不可移植的:

*((uint32_t*)&Record.Colours01[0]) = *((uint32_t*)&diagData[0]);
这将在x86上工作,但这只是因为该平台允许不对齐的访问。但是如果
diagData[0]
没有与4字节边界对齐(而且绝对没有理由假设它是对齐的),这就是未对齐的访问,很可能会触发其他平台上的陷阱(ARM具有对齐检查模式;IA-64和后期Alpha根本不支持未对齐的访问,就像各种嵌入式芯片一样)

因此,您甚至不能假设
colors01
是对齐的。编译器应该对齐它,实际上没有绑定的理由;堆栈上的其他变量很可能会使其失去对齐

无论对齐方式是什么,
memcpy
都是安全的,同时让编译器有机会将其优化到它认为最有效的方式(例如x86上的
mov
,未对齐的访问是安全的,并且可能比其他方式更快)


Lint抱怨这是Lint或
memcpy
上注释作者的一个严重错误。不管怎样,你都不应该遵循这条规则;这会导致更糟糕的代码。

您正在将相同的值复制到所有颜色变量中。源始终是
&diagData[0]
。你的意思是
&diagData[0]
&diagData[4]
&diagData[8]
?对不起,我已经正确修改了..它的顶部是frm diagData[0],1和2…在上面进行了修改..现在对于这个代码库,我得到了警告..@MariusBancila,如果索引是4的倍数,作为旁注,我将使用sizeof(uint8).我认为这是来自lint而不是编译器的消息,对吗?正如在前面提到的memcpy函数中,第三个参数是4..所以它等于4,条件(3n>4)…怎么不满足?@Ashwin:第三个参数4等于4,但不大于4,所以要求
(3n>4)
不满足
3n
指定第三个参数。根据我的算法..它应该是4..不超过4..那么我应该如何解决此警告???+1。。。比我的更快更完整。我只是添加了一个,其中声明它可以在编译时使用memcpy像intrinsic一样执行一些检查<代码>*(uint4*)和dest=*(uint4*)和源代码
memcpy(&Record, diagData, sizeof(Record));  
*((uint32_t*)&Record.Colours01[0]) = *((uint32_t*)&diagData[0]);