当前位置: 首页 > 知识库问答 >
问题:

memcpy零字节到const变量-未定义的行为?

漆雕正奇
2023-03-14

在 C 和 C 中,当要复制的字节数为零时,将 memcpy 转换为常量变量是否为未定义的行为?

int x = 0;
const int foo = 0;
memcpy( (void *)&foo, &x, 0 );

这个问题并不是纯粹的理论问题。我有一个场景,其中调用了memcpy,如果目标指针指向常量memory,那么大小参数保证为零。所以我想知道我是否需要把它作为一个特殊情况来处理。

共有2个答案

史烨
2023-03-14

在将本标准的部分和/或文档用于编译器或执行环境的情况下,会指定某些操作的行为,但本标准的其他部分可能会被解读为将其描述为未定义行为,是否以指定的有意义的方式处理行为的问题是实现质量问题。

如果出于某种原因,确保memcpy在大小参数为零的所有情况下始终表现为无操作是昂贵的,即使其中一个指针参数无效,标准也将允许编写符合要求的编译器的人通过生成始终将零大小memcpy视为无操作的代码来判断是否可以最好地满足客户的需求,或者通过生成代码来更快地确保指针可以识别所有size值的有效存储,但需要客户手动处理大小为零且指针无效的情况。

如果代码需要在一个编译器有充分理由以如此不同寻常的方式处理memcpy的平台上运行,或者在一个编译器上运行,其维护者可能会以标准的允许为借口以毫无意义的方式处理程序,那么就需要用代码来混淆程序,以解决实现中的这些怪癖。然而,如果一个人正在为高质量的实现编写不可移植的代码,这种变通办法会不必要地增加混乱并降低性能。

简意
2023-03-14

丙17

老一点的问题执行memcpy(0,0,0)能保证安全吗?7.1.4p1指出:

除非在随后的详细描述中另有明确说明,否则下面的每个语句都适用:如果函数的参数具有无效值(例如,函数域之外的值,或者程序地址空间之外的指针,或者空指针,或者当相应的参数不是const-qualified时指向不可修改的存储区的指针)或者具有可变数量的参数的函数所不期望的类型(提升后),则行为是未定义的。

< code>memcpy的原型是

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

其中第一个参数不是常量限定的,以及

memcpy函数将s2指向的对象中的n个字符复制到s1指向的目标中。

这意味着memcpy计数为0不会复制任何字符(这也通过7.24.1p2“复制零字符”得到了确认,谢谢Lundin),但它不能免除您传递有效参数的要求。

 类似资料:
  • 4.2.2 字节变量 定义字节变量的定义符为DB/BYTE(DefineByte),每个字节只占一个字节单元。其中:BYTE是MASM6.0及其以后版本的数据类型说明符,随后的其它类型说明符同此说明。 例如: COUNTER  DB 6  DB 'A', 'D',0Dh, '$' TABLE  DB 1, 3, 5, 7, 9, 11 上面的定义语句经汇编后所产生出的内存单元分配情况如图4.1所示

  • 问题内容: 当我尝试使用var定义变量时,一切正常。 但是将其定义为const不能按预期工作,并且该变量未定义。 我已经在Chrome和Node.js上对其进行了测试。我想念什么吗? 先感谢您! 问题答案: 在 eval 代码中使用 let 和 const 不会调用严格模式。 let 和 const 是 lexicalDeclarations ,将它们的范围限制为封闭的词法范围。 __ __ 词法

  • 问题内容: 在jQuery的核心风格指南建议两种不同的方法来检查一个变量是否被定义。 全局变量: 局部变量: 特性: 为什么jQuery为什么对全局变量使用一种方法而对局部变量和属性使用另一种方法? 问题答案: 对于未声明的变量,将返回字符串文字,而身份检查将触发错误 “未定义foo” 。 对于局部变量(您 知道 已在某处声明),不会发生此类错误,因此进行身份检查。

  • 问题内容: 作为Go“ newb”,我 不确定 在编译程序时为什么会在控制台中收到 未定义err 和 未定义用户 的错误。 我有: 我意识到我可以在条件块之前声明and 变量,但是我想知道为什么这不起作用。与一次性创建两个新变量有关吗? UDPATE 对此有些混乱。 我现在有: 和我的错误现在是 用户声明的,不使用 。目前,我还没有解决 错误的 部分,但是我不确定为什么会遇到用户错误。 问题答案:

  • 问题内容: 当我尝试引用永不设置或未设置的会话()时,我在核心CakePHP文件中出现错误: 我已经搜索了我的代码(在app /目录中),但是找不到对或的引用。我有什么想念的吗? 当我尝试运行任何单元测试时,都会显示此错误。这是正常的吗?我已经清除了目录,并用另一个目录(相同版本)替换了该目录,以确保我没有无意间修改了核心文件中的任何内容,但是仍然出现相同的错误。我不确定这是否只是框架中的缺陷或其

  • 我试图在MySQL中创建一个过程。这是正文: 但是当我保存它时,我得到这个错误: 处理您的请求时发生了一个或多个错误: 以下查询失败:“创建定义器”=root@localhost过程getAutoFinishTimeRemaining(按_order_id INT,按_Hoursint)非确定性读取SQL数据SQL安全定义器开始声明_date_delivered datetime;声明_date_