简体   繁体   English

如果我从未真正使用过引用,那么引用一个越界数组元素是否安全?

[英]Is it safe to have a reference to an out-of-bounds array element if I never actually use the reference?

I am working with an API wherein the caller passes in an array of pointers to stuff, as well as the length of the array. 我正在使用API​​,其中调用者传入一个指向数组的指针数组,以及数组的长度。 To make my code more readable/maintainable, I would like to be able to effectively give names to each argument rather than refer to them as arg[0] , arg[1] , etc. Is it safe to declare references to all of the possible arguments even if the length of the passed-in array can be different sizes due to optional arguments? 为了使我的代码更具可读性/可维护性,我希望能够有效地为每个参数赋予名称,而不是将它们称为arg[0]arg[1]等。声明对所有参数的引用是否安全即使由于可选参数传入的数组的长度可以是不同的大小,可能的参数?

I am trying to do something like this: 我想做这样的事情:

void myFunc(int out_args[], size_t nargs) {
  int &foo = out_args[0];
  int &bar = out_args[1];    // bar is optional argument. is this safe?
  ...
  foo = 5;
  if(2 >= nargs)
    bar = 10;
  ...
}

Note that the arguments are output arguments, so I really want to have references to them. 请注意,参数是输出参数,所以我真的想要引用它们。 So, is it safe to have a dangling-ish reference to args[1] if I never actually use it? 那么,如果我从未真正使用它,那么对args [1]进行悬空引用是否安全?

My guess is that this is safe because I imagine the way references are implemented is to treat & in the variable declaration of references as * const , and whenever I use the references, then the compiler automatically dereferences the pointers for me. 我的猜测是这是安全的,因为我想实现引用的方式是将引用的变量声明中的&作为* const ,并且每当我使用引用时,编译器会自动为我指出引用指针。 Ie, under the hood, I imagine that what I wrote is translated to something like 即,在引擎盖下,我想我写的东西被翻译成类似的东西

void myFunc(int out_args[], size_t nargs) {
  int *const foo = &out_args[0];
  int *const bar = &out_args[1];    // bar is optional argument. is this safe?
  ...
  *foo = 5;
  if(2 >= nargs)
    *bar = 10;
  ...
}

In this case, I believe the code never actually accesses memory it shouldn't, so if the version above is equivalent to this, then I should be ok, right? 在这种情况下,我相信代码永远不会实际访问内存它不应该,所以如果上面的版本等于这个,那么我应该没问题,对吧?


EDIT: I'm basically writing a plug in, and the API I'm using and can't do anything about can call my code with either something like 编辑:我基本上写了一个插件,我正在使用的API,无法做任何事情可以用类似的东西调用我的代码

int ret_vals[1];     // only care about 1 return value
myFunc(ret_vals, 1);

or 要么

int ret_vals[2];     // care about both return values
myFunc(ret_vals, 2);

or even 甚至

myFunc(NULL, 0);     // ignore all return values; just marvel at the side effects

and my code needs to work in all cases. 我的代码需要适用于所有情况。

It is undefined behaviour to evaluate the expression args[1] if args isn't a pointer to the first element of an array of at least two elements. 如果args不是指向至少两个元素的数组的第一个元素的指针,则评估表达式args[1]是未定义的行为。 Taking the address immediately, like &args[1] , is valid only if args points to the first element of an array of at least one element. 仅当args指向至少一个元素的数组的第一个元素时,立即获取地址(如&args[1] )才有效。

Basically, don't do it. 基本上,不要这样做。

So, is it safe to have a dangling-ish reference to args[1] if I never actually use it? 那么,如果我从未真正使用它,那么对args [1]进行悬空引用是否安全?

The standard impose that a reference shall be bound to a valid object in § 8.3.2: 该标准规定引用应与第8.3.2节中的有效对象绑定:

There shall be no references to references, no arrays of references, and no pointers to references. 不应引用引用,不引用引用数组,也不引用引用指针。 [...] A reference shall be initialized to refer to a valid object or function. [...]应初始化引用以引用有效的对象或函数。 [ Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. [注意:特别是,在一个定义良好的程序中不能存在空引用,因为创建这样一个引用的唯一方法是将它绑定到通过解除引用空指针获得的“对象”,这会导致未定义的行为。 [...] — end note ] [...] - 结束说明]

It means that it is not safe. 这意味着它是不是安全。

My guess is that this is safe because I imagine the way references are implemented is to treat & in the variable declaration of references as * const, and whenever I use the references, then the compiler automatically dereferences the pointers for me. 我的猜测是这是安全的,因为我想实现引用的方式是将引用的变量声明中的&作为* const处理,并且每当我使用引用时,编译器会自动为我指出引用指针。

No, don't do that. 不,不要那样做。 Again, the standard doesn't specify how references shall be implemented. 同样,该标准没有规定如何实施参考。 In fact in § 8.3.2 it states that: 事实上,在第8.3.2节中,它指出:

It is unspecified whether or not a reference requires storage. 未指定引用是否需要存储。

As for your code: you could name the parameters once you are sure they exists. 至于你的代码:一旦你确定它们存在,就可以命名参数。

void myFunc(int out_args[], size_t nargs) {
  int &foo = out_args[0];
  ...
  foo = 5;
  if(nargs >= 2) {
    int &bar = out_args[1];
    bar = 10;
  }
  ...
}

I feel obligated to make you notice that the use of C-style arrays in C++ is discouraged. 我觉得有必要让你注意到不鼓励在C ++中使用C风格的数组。 It is generally a good idea to use std::vector or std::array instead. 通常使用std::vectorstd::array是个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM