【问题标题】:Will "&a+1 > &a" cause an undefined behaviour"&a+1 > &a" 会导致未定义的行为吗
【发布时间】:2013-04-24 10:39:17
【问题描述】:

c99/c++03 是否保证&a+1 > &a 始终为真?

例如,有一个(c-like)std::copy,并且

int a = 0 ;
int b[9] ;
std__copy(&a , &a+1 , b) ;

这总是有效吗?

【问题讨论】:

  • 是的,虽然@MOHAMED 的答案是指数组,但对于一个简单的对象来说,原理是一样的。
  • @MOHAMED,不,那不一样。数组的情况是没有问题的,但非数组变量必须有特殊的写法。
  • 如果 UB 用于 C90 和 C++98,则从内存中得到答案,对 C11 和 C++11 有效,但我不记得是否及时对 C99 和 C++03 进行了澄清;-(

标签: c++ c c99 c++03


【解决方案1】:

是的,C99 有一个特殊的措辞,即在处理地址时,任何给定的对象 a 都会像一个包含 1 项的数组一样,因此 &a+1 是有效的(第 6.5.6/7 节):

就这些运算符而言,指向不是元素的对象的指针 数组的行为与指向长度为 1 的数组的第一个元素的指针相同 对象的类型作为其元素类型。

虽然章节编号不同(第 6.3.6 节),但 C90 给出了相同的要求。

C++ 在 §5.7/4 中具有相同的要求(C++03 和 C++11 中的节号相同)。

在 C++ 中,您可以使用 std::less 比较任意对象(相同类型)的地址,即使内置的 < 运算符不会产生有意义的结果(例如,两个不属于同一类型的对象)数组)(§20.8.5/7):

对于模板greaterlessgreater_equalless_equal,任何指针类型的特化都会产生一个总顺序,即使内置运算符 、= do不是。

还请注意,虽然您可以形成这些地址,并将它们与对象的地址进行比较,但您不能取消引用这些指针(好吧,如果您尝试编译器可能不会阻止您,但结果将是未定义的行为)。

【讨论】:

  • 有趣,我从来不知道std::less 可以用来比较任意地址。该标准究竟如何保证这一点?
【解决方案2】:

是的,这在 C++ 中得到保证(不了解 C)。具体来说,T类型的变量相当于一个相同类型的单个元素组成的数组,而且总是可以得到一个超出数组末尾的指针。

【讨论】:

  • 如果它具有相同的数组对象原理,您必须在答案中提到 &a+1 的指针引用被禁止
  • @MOHAMED:好吧,OP 没有取消引用它,所以它与答案也不是很相关:)
  • 我知道只是为了让他在使用这种行为时更加小心:-)
  • @MOHAMED:他的示例类似于std::copy,并且在该模板中,end 迭代器永远不会被取消引用。你是对的,也许我应该更明确一点,但如果意图是将单个对象传递给一个在 ranges 上工作的函数的实现(在迭代器对的意义上),那是完美的有效。
猜你喜欢
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 2014-09-24
  • 2013-04-19
  • 1970-01-01
  • 2014-08-11
  • 2016-09-04
  • 1970-01-01
相关资源
最近更新 更多