空引用 [英] Null reference

查看:85
本文介绍了空引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我差点把头发撕掉。一位同事声称可以存在空引用,例如

这个:


void f(int& p)

{

printf("%d \ n",p);

}


int main(int argc,char * argv [])

{

int * p = NULL;


f(* p);


返回0;

}


我向他指出了C ++标准的相关部分,禁止在明确定义的

计划,但他反驳说,在现实世界中引用可以是空。随后发生了一个争论

,他设法引起了另外两位同事的担忧,因为上面代码中的

崩溃很可能发生在使用引用的地方,这可能是

在任何地方,而不是取消引用空指针的地方。一个人(用C ++获得很少经验的b $ b)甚至说参考文献不应该用在安全关键代码中。另一个因为他总是假设引用必须引用有效的

对象而引起关注,现在他想知道他是否应该测试一个b $ b对象。一个函数需要参考参数的地方,至少用一个

断言的空引用。


我已经尝试了我能想到的所有东西返回为了一些理智,但无济于事。我已经告诉

他们:

- 上面代码中的问题不是引用,而是取消引用null

指针,这是一个普通的错误,每个人都知道要避免。

- 我不记得实际遇到的空引用在使用C ++十年的实际程序中的错误


- 你可以做的事情有一百万可以导致未定义的行为,所以为什么要

特别关注这一个?

- 在导致执行的代码

之后很长时间内,有多种方法可以显示错误?例如,保持指向随后被删除的对象的指针),

为什么要特别关注这个呢?


他们仍然不相信null reference这不是一个值得关注的潜在问题,而且我正在寻找关于我还能说什么来实现它的想法

完全雷达,其中它属于(如果这里的人与我同意

课程)。


David

解决方案

* David W:


我几乎要撕掉我的头发了。一位同事声称可以存在空引用,例如

这个:


void f(int& p)

{

printf("%d \ n",p);

}


int main(int argc,char * argv [])

{

int * p = NULL;


f(* p);


返回0;

}


我向他指出了C ++标准的相关部分,禁止在明确定义的

计划,但他反驳说,在现实世界中引用可以是空。随后发生了一个争论

,他设法引起了另外两位同事的担忧,因为上面代码中的

崩溃很可能发生在使用引用的地方,这可能是

在任何地方,而不是取消引用空指针的地方。一个人(用C ++获得很少经验的b $ b)甚至说参考文献不应该用在安全关键代码中。另一个因为他总是假设引用必须引用有效的

对象而引起关注,现在他想知道他是否应该测试一个b $ b对象。一个函数需要参考参数的地方,至少用一个

断言的空引用。


我已经尝试了我能想到的所有东西返回为了一些理智,但无济于事。我已经告诉

他们:

- 上面代码中的问题不是引用,而是取消引用null

指针,这是一个普通的错误,每个人都知道要避免。

- 我不记得实际遇到的空引用在使用C ++十年的实际程序中的错误


- 你可以做的事情有一百万可以导致未定义的行为,所以为什么要

特别关注这一个?

- 在导致执行的代码

之后很长时间内,有多种方法可以显示错误?例如,保持指向随后被删除的对象的指针),

为什么要特别关注这个呢?


他们仍然不相信null reference这不是一个值得关注的潜在问题,而且我正在寻找关于我还能说什么来实现它的想法

完全雷达,其中它属于(如果这里的人与我同意

课程)。



取消引用nullpointer是正式未定义的行为。


但它可能发生,并且使用的结果那个参考是坏的

事情发生。


获得无效引用的另一种方法是销毁一个对象

some代码的其他部分包含引用(最简单的方法是执行

这是为了返回对局部变量的引用),这会产生一个

悬空引用。 br />

参考文献不买你技术安全:空引用和悬空

引用可以存在 - 但是空引用不存在于有效的

程序,悬挂的参考文献不能在有效的程序中使用。


而不是技术安全参考给你带来简单和清晰
/意图通信/,即这是为了永远不会为空,加上

统一表示法的可能性(例如索引,可以在模板代码中应用

),所有这些都会为您带来安全和生产力。


当您的函数被传递为空引用或悬空引用时

知道这是调用代码中的错误。当一个空指针或

悬空指针出现时,你不一定知道这是一个错误的调用代码

。也许你需要处理空指针(并且

结果是凌乱检查并决定在这种情况下做什么或不做什么,

使事情变得复杂,并导致更多相同的,更多的错误。


总结一下,你的第一个同事是对的,空引用可以存在b $ b,但不是它们可以存在于一个有效的程序。而且你确实这种情况在实践中几乎从未发生过。因为

除了更简单的表示法之外,参考点就是传达

它的意图永远不会为空或无效,所以没人会
尝试将其设置为空引用。


您的同事认为参考不应该用于

安全关键代码完全倒退。


-

答:因为它弄乱了人们通常阅读文本的顺序。

问:为什么这么糟糕?

A:热门发布。

问:usenet和电子邮件中最烦人的是什么?


" Alf P. Steinbach" < al *** @ start.nowrote in message news:4i ************ @ individual.net ...


>

取消引用nullpointer是正式未定义的行为。


但它可能发生,使用该引用的结果是Bad < b / b
发生的事情。


获取无效引用的另一种方法是销毁一个对象,该代码中包含其他部分代码引用(最简单的方法是

这是为了返回对局部变量的引用),这会产生一个

悬空引用。

参考文献不会给你带来技术安全:空引用和悬空

引用可以存在 - 但空引用不能存在于有效的
$中b $ b程序,悬挂参考不能在有效的程序中使用。


而不是技术安全参考给你带来简单和清晰

/意图的沟通/,即这是我为了统一表示法的可能性(例如,加上

)索引,可以在模板代码中应用

),这些都可以为您带来安全和生产力。



好​​点。


当您的函数传递空引用或悬空引用时/>
知道这是调用代码中的错误。当一个空指针或

悬空指针出现时,你不一定知道这是一个错误的调用代码

。也许你需要处理空指针(并且

结果是凌乱检查并决定在这种情况下做什么或不做什么,

使事情变得复杂,并导致更多相同的,更多的错误)。


总结一下,你的第一个同事是对的,空引用可以存在



嗯,实际上,当我向受访者询问

指针和参考文献之间的差异时,这开始了,他说有一个区别是参考文件不能是

null。采访结束后,我的同事声称他错了。在

采访的背景下 - 纯C ++问题而不考虑实际的

编译器的常规实现 - 我会说我的同事错了。


但不是它们可以存在于有效的程序中。而且你确实这种情况在实践中几乎从未发生过。因为

除了更简单的表示法之外,参考点就是传达

它的意图永远不会为空或无效,所以没人会
尝试将其设置为null-reference。



好​​点。


你的同事认为参考文献不应该用于

安全关键代码完全倒退了。



谢谢。


David


David W发布了:


他们仍然不相信null reference。这不是一个值得关注的潜在问题,而且我正在寻找关于我能说些什么才能让它完全脱离雷达的想法想法

它所属的地方(如果这里的人当然同意我的话)。



你是对的。你的同事错了。简单明了。


(1)取消引用空指针是未定义的行为。

(2)它是未定义的行为空引用。


你和你的同事需要讨论的不是空引用是否b / b $ b是一件好事,而是你是否想写便携式,标准

符合C ++标准的代码。


目前,它不是可移植的,符合标准C ++的代码。

如果你想要某种类型的空引用,可以试试类似:

struct AlignedByte {


char unsigned * const p;


AlignedByte():p(new char unsigned){}


~AlignedByte(){delete p; }


} aligned_byte;


模板< class T>

内联T& NullRef()

{

返回reinterpret_cast< T&>(* aligned_byte.p);

}


模板< class T>

inline bool IsNull(T& ref)

{

return reinterpret_cast< char unsigned const *>(& ; ref)== aligned_byte.p;

}


/ *以下是使用演示代码* /


#include< string>

使用std :: string;


void SomeFunc(string& arg)

{

if(IsNull(arg))返回;


arg + =" success";

}


int main()

{

string obj =" doctor";


SomeFunc(obj);


SomeFunc(NullRef< string>());

}

-


Frederick Gotham


I''m almost tearing my hair out. A colleague claimed that a null reference can exist, like
this:

void f( int& p )
{
printf( "%d\n", p );
}

int main (int argc, char *argv[])
{
int*p= NULL;

f( *p );

return 0;
}

I pointed him to the relevant part of the C++ standard that forbids this in a well-defined
program, but he countered that in the "real world" a reference can be "null". An argument
then ensued in which he managed to raise concerns with two other colleagues because the
crash in the above code is likely to occur where the reference is used, which could be
anywhere, not where the null pointer is dereferenced. One (who has had little experience
with C++) even said that references "shouldn''t be used in safety critical code". The other
became concerned because he''d always assumed that a reference has to refer to a valid
object, and now he wonders whether he should test for a "null reference", at least with an
assert, wherever a function takes a reference parameter.

I''ve tried everything I can think of to return to some sanity, but to no avail. I''ve told
them:
- That the problem in the code above is not the reference but the dereference of a null
pointer, which is a normal bug that everyone knows to avoid.
- That I can''t recall actually coming across a "null reference" bug in a real program in
over a decade of using C++
- That there are a million things you can do that can cause undefined behaviour, so why be
specifically concerned about this one?
- That there are a multitude of ways that a bug can manifest itself long after the code
that caused it executes (e.g., keep a pointer to an object that is subsequently deleted),
so why be specifically concerned about this one?

They are still not convinced that the "null reference" is not a potential problem that
deserves some attention, and I''m looking for ideas as to what else I can say to get it off
the radar completely, where it belongs (that''s if the people here agree with me of
course).

David

解决方案

* David W:

I''m almost tearing my hair out. A colleague claimed that a null reference can exist, like
this:

void f( int& p )
{
printf( "%d\n", p );
}

int main (int argc, char *argv[])
{
int*p= NULL;

f( *p );

return 0;
}

I pointed him to the relevant part of the C++ standard that forbids this in a well-defined
program, but he countered that in the "real world" a reference can be "null". An argument
then ensued in which he managed to raise concerns with two other colleagues because the
crash in the above code is likely to occur where the reference is used, which could be
anywhere, not where the null pointer is dereferenced. One (who has had little experience
with C++) even said that references "shouldn''t be used in safety critical code". The other
became concerned because he''d always assumed that a reference has to refer to a valid
object, and now he wonders whether he should test for a "null reference", at least with an
assert, wherever a function takes a reference parameter.

I''ve tried everything I can think of to return to some sanity, but to no avail. I''ve told
them:
- That the problem in the code above is not the reference but the dereference of a null
pointer, which is a normal bug that everyone knows to avoid.
- That I can''t recall actually coming across a "null reference" bug in a real program in
over a decade of using C++
- That there are a million things you can do that can cause undefined behaviour, so why be
specifically concerned about this one?
- That there are a multitude of ways that a bug can manifest itself long after the code
that caused it executes (e.g., keep a pointer to an object that is subsequently deleted),
so why be specifically concerned about this one?

They are still not convinced that the "null reference" is not a potential problem that
deserves some attention, and I''m looking for ideas as to what else I can say to get it off
the radar completely, where it belongs (that''s if the people here agree with me of
course).

It''s formally undefined behavior to dereference a nullpointer.

But it can happen, and the result of using that reference is that Bad
Things Happen.

Another way to obtain an invalid reference is to destroy an object that
some other part of the code holds a reference to (the simplest way to do
this is to return a reference to a local variable), which yields a
dangling reference.

References don''t buy you technical safety: null-references and dangling
references can exist -- but null-references can''t exist in a valid
program, and dangling references can''t be used in a valid program.

Instead of technical safety references buy you simplicity and clear
/communication of intent/, i.e. this is intended to never be null, plus
the possibility of unified notation (e.g. indexing, which can be applied
in template code), all which in turn buys you safety and productivity.

When your function is passed a null-reference or dangling reference you
know that it''s an error in the calling code. When a null-pointer or
dangling pointer occurs you don''t necessarily know that it''s an error in
the calling code. Perhaps you need to handle null-pointers (and the
result is messy checking and deciding what to do or not in that case,
which complicates things, and leads to more of the same, more bugs).

Summing up, your first colleague was right that null-references can
exist, but not that they can exist in a valid program. And you were
right that that situation almost never occurs in practice. Because
apart from simpler notation, the point of a reference is to communicate
that it''s intended to never be null or otherwise invalid, so nobody will
try to set it to null-reference.

Your colleague who maintained that references shouldn''t be used in
safety-critical code got it exactly backwards.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


"Alf P. Steinbach" <al***@start.nowrote in message news:4i************@individual.net...

>
It''s formally undefined behavior to dereference a nullpointer.

But it can happen, and the result of using that reference is that Bad
Things Happen.

Another way to obtain an invalid reference is to destroy an object that
some other part of the code holds a reference to (the simplest way to do
this is to return a reference to a local variable), which yields a
dangling reference.

References don''t buy you technical safety: null-references and dangling
references can exist -- but null-references can''t exist in a valid
program, and dangling references can''t be used in a valid program.

Instead of technical safety references buy you simplicity and clear
/communication of intent/, i.e. this is intended to never be null, plus
the possibility of unified notation (e.g. indexing, which can be applied
in template code), all which in turn buys you safety and productivity.

Good point.

When your function is passed a null-reference or dangling reference you
know that it''s an error in the calling code. When a null-pointer or
dangling pointer occurs you don''t necessarily know that it''s an error in
the calling code. Perhaps you need to handle null-pointers (and the
result is messy checking and deciding what to do or not in that case,
which complicates things, and leads to more of the same, more bugs).

Summing up, your first colleague was right that null-references can
exist,

Well, actually this started when I asked an interviewee what the differences were between
pointers and references, and he said that one difference was that a reference couldn''t be
null. After the interview my colleague claimed that he was wrong. In the context of the
interview - pure C++ questions without considering the usual implementation on actual
compilers - I would say that my colleague was wrong.

but not that they can exist in a valid program. And you were
right that that situation almost never occurs in practice. Because
apart from simpler notation, the point of a reference is to communicate
that it''s intended to never be null or otherwise invalid, so nobody will
try to set it to null-reference.

Good point.

Your colleague who maintained that references shouldn''t be used in
safety-critical code got it exactly backwards.

Thank you.

David


David W posted:

They are still not convinced that the "null reference" is not a
potential problem that deserves some attention, and I''m looking for
ideas as to what else I can say to get it off the radar completely,
where it belongs (that''s if the people here agree with me of course).


You are correct. Your colleagues are wrong. Plain and simple.

(1) It''s undefined behaviour to dereference a null pointer.
(2) It''s undefined behaviour to have a null reference.

What you and your colleagues need to debate is NOT whether a null reference
is a good thing, but rather whether you want to write portable, Standard
C++-compliant code.

At the moment, it is NOT portable, Standard C++-compliant code.

If you want some sort of null reference maybe try something like:
struct AlignedByte {

char unsigned * const p;

AlignedByte() : p(new char unsigned) {}

~AlignedByte() { delete p; }

} aligned_byte;

template<class T>
inline T &NullRef()
{
return reinterpret_cast<T&>(*aligned_byte.p);
}

template<class T>
inline bool IsNull(T &ref)
{
return reinterpret_cast<char unsigned const*>(&ref) == aligned_byte.p;
}

/* Here comes the usage demonstration code */

#include <string>
using std::string;

void SomeFunc(string &arg)
{
if (IsNull(arg)) return;

arg += "success";
}

int main()
{
string obj = "doctor";

SomeFunc(obj);

SomeFunc( NullRef<string>() );
}
--

Frederick Gotham


这篇关于空引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆