【问题标题】:error: implicit declaration of function ‘memcpy_s’; did you mean ‘memcpy’? [-Werror=implicit-function-declaration]错误:函数“memcpy_s”的隐式声明;你的意思是“memcpy”吗? [-Werror=隐式函数声明]
【发布时间】:2021-11-18 12:44:04
【问题描述】:

我正在尝试调用 memcpy_s()。下面是我观察警告的代码 sn-p “错误:函数‘memcpy_s’的隐式声明;你的意思是‘memcpy’吗?[-Werror=implicit-function-declaration]”

#include <stdio.h>
#include <string.h>
#include <stdint.h>

static const uint32_t ab[10] = {0,1,2,3,4,5,6,7,8,9};
void main()
{
  uint32_t u[10];
  memcpy_s((void *)&u[0], sizeof(u), (void *)&ab[0], 10 * sizeof(uint32_t));
  
}

【问题讨论】:

  • sizeof ab 在哪里?它的类型是什么?
  • 显然memcpy_s 在您的平台上不可用。但是无论如何,该函数都毫无用处,尤其是在您忽略返回值的情况下。见这里:en.cppreference.com/w/c/string/byte/memcpy。无论如何:只需使用memcpy 并忘记memcpy_s
  • 修复void*)语法错误后,它确实可以用MS VC编译。
  • @Jabberwocky 是的,我知道这一点,但是马虎的 默认为 int 加上偏执的附件-K 固定让我感到困惑。 [更不用说void main() 和不必要的(void*) 演员]
  • @Coder 不,您在#include &lt;string.h&gt; 之前缺少#define __STDC_WANT_LIB_EXT1__。但即使这样也无济于事……奇怪。还是试试吧

标签: c


【解决方案1】:

您使用的 IDE/平台似乎不支持 memcpymemcpy_s() 变体,IMO 很好! 我建议改用memcpy()

如果您之前没有使用过 --

看着reference page for memcpy

void *memcpy(void *restrict dest, const void *restrict src, size_t n);

它需要以下参数:

dest - 指向要复制到的对象的指针
src - 指向要从中复制的对象的指针
n -要复制的字节数

所以,

memcpy((void*)&u[0], (void*)&ab[0], 10*sizeof(uint32_t));

或者更好,

memcpy((void*)&u[0], (void*)&ab[0], COUNT_OF(ab)*sizeof(uint32_t));
//                                  ↑ Note this!

用一个简约的、不那么完美的宏来获取数组中元素的数量:

#define COUNT_OF(var)   (sizeof(var)/sizeof(var[0]))

顺便说一句,您的代码中有一个错字:

memcpy_s(void *)&u[0], sizeof(u), (void*)&ab[0], 10*sizeof(uint32_t));
//      ↑      ↑ ouch!

是括号。如果您完全迁移到支持memcpy_s() 的平台,请将其更改为:

memcpy_s((void*)&u[0], sizeof(u), (void*)&ab[0], COUNT_OF(ab)*sizeof(uint32_t));

更新:

我从 OP 那里了解到,实际的分配是编写一个行为类似于memcpy() 的函数。 假设参数的性质与memcpy() 需要的保持一致,添加return 以指示复制是否成功,当然您可以添加更多。

一个最小的、简单的版本可以编程为:

int my_memcpy(void *pDest, void *pSrc, size_t sz)
{
    char *src = (char *)src;   // Or use uint8_t instead of char
    char *dest = (char *)dest; // Or use uint8_t instead of char
    
    // Validate pointers to avoid seg-faults
    if(NULL == pDest || NULL == pSrc) {
        return -1;
    }
        
    // Copy contents
    for (int i = 0; i < sz; i++) {
        dest[i] = src[i];
    }
    return 0;
}

【讨论】:

  • uint32_t u0[10]; uint32_t u1[10]; uint32_t u2[10]; uint32_t u3[10]; (void)memcpy(u0, ab, 10 * sizeof(uint32_t)); (void)memcpy_s((void *)&u1[0], sizeof(u1), (void *)&ab[0], 10 * sizeof(uint32_t)); (void)memmove(u2, ab, 10 * sizeof(uint32_t)); (void)memmove_s((void *)&u3[0], sizeof(u3), (void *)&ab[0], 10 * sizeof(uint32_t)); // 结果值在 u0 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 中相同; u1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; u2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; u3 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  • 显然我尝试了几种方法,我得到了相同的结果。有了以上所有的说明,并且我达到了摆脱错误的地步,我必须编写 memcpy_s 内置函数,因为我不能直接在我的代码中使用 memcpy_s 。获取 memcpy_s() 源代码的任何链接或帮助?
  • 当你说“我必须写memcpy_s内置函数,因为我不能在我的代码中直接使用memcpy_s”,你的意思是你想写你自己的函数哪个执行 memcpy()memcpy_s() 函数调用的确切操作?
  • 是的。你的理解是对的。重写内置函数。
  • 为什么不直接使用sizeof(ab) 而不是COUNT_OF(ab) * sizeof(uint32_t)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 2015-09-27
  • 2013-03-20
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多