NULL直接传递给需要const引用形参的函数(vc++ 4.2)
NULL passed directly to a function expecting a const reference parameter (VC++ 4.2)
我正在看一些我在旧代码库中发现的东西,我很困惑。
下面是一个函数定义:
void vUpdateSequenceDetailsAndIncrement(
const CallEvent& roCPEvent,
const CallInfo& roCallInfo,
BOOL bCreationEvent);
这里叫做
vUpdateSequenceDetailsAndIncrement(roCPEvent, NULL, FALSE);
这里NULL被直接传递给引用参数roCallInfo
。这个函数最终调用:
vTimeChange(*pSeqDetails, roCPEvent, roCallInfo);
定义为:
void vTimeChange(const SequenceDetails& roSequenceDetails,
const CallEvent& roCPEvent,
const CallInfo& roCallInfo)
再次传递可能为NULL的值给roCallInfo
。我以为NULL不能作为引用传递?有人知道vc++ 4。X出现了一些问题使得这种代码可以吗?如果NULL可以作为引用传递,那么在vTimeChange中发生类似这样的事情时会发生什么:
roCallInfo.getCallStartTime();
这不是NULL的解引用吗?就像我要做
一样?CallInfo * info = NULL;
info->getCallStartTime();
?我可能会在那里放置一个保护,如果不需要,让编译器删除它,但我很想了解这是如何发生的!
谢谢。
取决于vc4.2中NULL的定义
如果只是
#define NULL 0
那么你实际上得到了这个:
vUpdateSequenceDetailsAndIncrement(roCPEvent, CallInfo(0), FALSE);
和CallInfo类型的临时变量的引用传递给函数(如果CallInfo有兼容的变量)
我以为NULL
不能作为参考传递吗?
有效的引用不能为空,但无效的引用可以为空。
这里是一个无效引用。
引用不能为空并不意味着引用在某种程度上比指针更安全,正如你在这里看到的那样。程序可能导致无效引用的方式有很多种,您的代码就是这样一个例子。
参考维基百科:
事实上,reference
也可以从invalid
开始。由于引用通常作为基础指针实现,因此在指针解引用表达式上初始化引用通常由编译器实现为从指针到引用的基础指针的简单赋值。因此,如果您有一个NULL
指针或指向内存中无效位置的指针,您实际上会有一个指向NULL或无效位置的引用。c++纯粹主义者认为,从技术上讲,解引用NULL或无效指针无论如何都会导致未定义的行为,因此这并不违反上面的断言,即引用不能为空或指向内存中的任意位置。然而,这忽略了这样一个事实:在这种情况下,底层实现只是执行一个"赋值",并且不涉及对内存位置的访问,因此引用的这种初始化通常不会引起问题,程序员必须意识到在实际程序中存在事实上"无效"引用的可能性。
使用无效引用 roSequenceDetails
最终会导致未定义行为
如果pSeqDetails
为空,则表达式*pSeqDetails
将导致未定义的行为。任何事情都有可能发生。大多数实现不做任何特别的检查;你的代码似乎可以工作,直到你做一些真正需要这个对象的事情,然后它就会失败。但是一个实现可能会导致它立即失败。
- 使用mem_fun_ref if成员函数需要多个形参
- 哪个模板形参在boost::shared_ptr构造函数中使用一个原始指针
- 如何在编译时通过模板形参默认值的名称/指针获取函数的类型
- 哪种方法更适合为函数提供编译时间常数?函数实参与模板形参
- 包含void*结构的函数的Const正确性和形参
- 将函数形参的实参解包到c++模板类
- c++ const函数形参.有没有一种方法可以只声明函数的单个签名?
- 关于将指向数组的指针作为函数形参的混淆
- 将非const引用使用auto-keyword声明的lambda作为实参传递给std::函数形参类型
- 作为函数形参传递的Vector初始化器列表
- 指向函数形参的指针vs函数形参
- 在模板化类和函数上下文中以默认值作为函数形参的函子:-)
- 带std::函数形参的重载操作符
- 作为Const引用的函数形参
- Const对象作为函数形参
- 函数形参中的指针
- 使用关键字作为C函数形参或c++模板参数
- 在不调用initializer_list构造函数的情况下,将不可复制、不可移动的类型构造为函数形参
- 模板类复制构造函数形参,带或不带模板实参
- c++中函数形参中的右值引用