【问题标题】:C - Is charArray always the same as &charArray?C - charArray 是否总是与 &charArray 相同?
【发布时间】:2016-10-05 09:48:00
【问题描述】:

我正在阅读an article about whole program optimization。链接时间代码生成部分的最后一段说,将分配在堆栈上的数组归零可能不会产生相同的效果,具体取决于它的归零方式:

开启整个程序优化确实发现了几个具有未定义行为的错误。如果没有 WPO,这些都不会以某种方式崩溃。有了 WPO,他们做到了。在一种情况下,成员函数调用是通过指向未初始化内存的指针进行的。在其他几种情况下,假设堆栈上的数组与其自己的地址相同。 也就是说,假设 memset(&charArray, 0, sizeof(charArray)) 将具有与 memset(charArray, 0, sizeof(charArray)) 相同的效果。标准不保证这一点,并且在 WPO 下似乎有所改变。

我想如果我做了char foo[1],那么foo 将永远是==&foo。有人可以解释这里发生了什么吗?谢谢

【问题讨论】:

  • 这取决于作为函数参数传递的变量。在char array[10] 的情况下,例如函数scanf,无论您传递array 还是&array,都将起作用。但是如果数组是动态获得的,比如array = malloc(10),那么它就非常重要了。在那种情况下array&array 是非常不同的。
  • @WeatherVane;不会。编译器会针对&array 发出警告。
  • @hacks 大概是在第一种情况下,是编译器警告,但功能正确。显然是第二种情况。
  • 由于我们不知道charArray的类型是什么,所以这个问题没有明确的答案。
  • 这里的静态数组与 malloc 内存的真正傻瓜是sizeof

标签: c


【解决方案1】:

foo 是一个数组,在表达式中foo 将转换为指向其第一个元素的指针,除非是一元&sizeof 运算符的操作数。所以,在这种情况下foo == &foo[0]&foo 是数组foo 的地址,而不是foo 的第一个元素的地址。
虽然foo&foo 的值是等价的,但是它们的类型是不同的。 foo 在衰减后属于char * 类型,而&foo 属于char (*)[1] 类型。

【讨论】:

  • 所以你是说foo真的只相当于&foo[0]
  • 这如何应用于memset 示例,我们应该得出什么结论?存在 LTCG/WPO 时它如何变化?
  • @newguy;是的,但是正如我在答案中提到的那样在衰减之后。
  • @Drop; array&array 的指针运算会有所不同。对于char foo[2],如果memset(&foo, sizeof(foo), 0) 开始填充第一个字节并递增传递的指针以填充另一个,那么它将填充foo[1] 旁边的元素而不是它。此内存位置未分配,写入未分配的内存位置将导致未定义的行为。
  • 但是为什么memset(foo, 0, sizeof(foo))memset(&foo, 0, sizeof(foo)) 之间会有区别(假设例如char foo[1])?如果我正确理解您的答案,foo&foo 都会计算为第一个元素的地址,因此 memset() 不会有任何区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2014-04-28
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多