Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用带引用的函数作为带指针的函数?_C++_Casting_Pass By Reference_Parameter Passing - Fatal编程技术网

C++ 使用带引用的函数作为带指针的函数?

C++ 使用带引用的函数作为带指针的函数?,c++,casting,pass-by-reference,parameter-passing,C++,Casting,Pass By Reference,Parameter Passing,今天我无意中发现了一段代码,这段代码看起来很恐怖。这些片段在不同的文件中被讨论过,我试着在下面一个简单的测试用例中写出它的要点。代码库每天都会使用FlexeLint进行常规扫描,但这种结构自2004年以来就一直存在于代码中 问题是,使用引用传递参数实现的函数被称为使用指针传递参数的函数…这是由于函数转换。该构造自2004年在Irix上运行以来,现在在移植它时实际上也在Linux/gcc上运行 我现在的问题是。这是一个可以信任的结构吗?我可以理解编译器构造函数是否将引用传递作为指针来实现,但它可靠

今天我无意中发现了一段代码,这段代码看起来很恐怖。这些片段在不同的文件中被讨论过,我试着在下面一个简单的测试用例中写出它的要点。代码库每天都会使用FlexeLint进行常规扫描,但这种结构自2004年以来就一直存在于代码中

问题是,使用引用传递参数实现的函数被称为使用指针传递参数的函数…这是由于函数转换。该构造自2004年在Irix上运行以来,现在在移植它时实际上也在Linux/gcc上运行

我现在的问题是。这是一个可以信任的结构吗?我可以理解编译器构造函数是否将引用传递作为指针来实现,但它可靠吗?是否存在潜在风险

我是否应该将
fref(..)
更改为使用指针并在过程中冒险制动

你觉得怎么样

编辑 在实际代码中,
fptr(..)
fref(..)
都使用相同的
struct
-下面更改的代码以更好地反映这一点

#包括
#包括
使用名称空间std;
// ----------------------------------------
//这将作为fref(..)中的引用传递
结构字符串{
char-str[256];
};
// ----------------------------------------
//在这里使用指针!
void fptr(字符串结构*str)
{

这完全是偶然的

fptr需要const char*,而fref需要string_struct&

struct string_struct与const char*具有相同的内存布局,因为它只包含一个256字节的char数组,并且没有任何虚拟成员

C++中,通过引用调用StrugJuthStutt,通过将一个隐藏指针传递给引用,这样调用栈就如同传递了一个真正的指针一样。


但是,如果结构字符串_struct发生更改,所有内容都将中断,因此代码根本不被认为是安全的。此外,它取决于编译器的实现。

让我们同意这是非常难看的,您将更改代码。 在演员阵容中,你保证确保类型匹配,但他们显然不匹配。 至少摆脱C风格的演员阵容

你觉得怎么样

清理它。这是未定义的行为,因此是一颗随时可能爆炸的炸弹。一个新的平台或编译器版本(或月球阶段,就这一点而言)可能会使它崩溃


当然,我不知道真正的代码是什么样子的,但是从您的简化版本来看,最简单的方法似乎是给
string_struct
一个隐式构造函数,它采用
const char*
,templatize
ftest()
,并删除所有涉及的强制转换。

这显然是一种可怕的技术,从形式上讲,通过不兼容的类型调用函数是一种未定义的行为和严重错误,但实际上在正常系统上应该“起作用”

在机器级别上,引用和指针具有完全相同的表示形式;它们都只是某个东西的地址。我完全希望
fptr
fref
在任何一台计算机上编译成完全相同的东西,指令对指令。这种上下文中的引用可以简化y可以被认为是语法糖;一个为您自动取消引用的指针。在机器级别,它们完全相同。显然,可能存在一些模糊和/或失效的平台,但通常情况下99%都是这样

此外,在大多数常见的平台上,所有对象指针和所有函数指针都具有相同的表示形式。您所做的工作实际上与在一个平台上通过一个需要较长时间的类型调用一个需要int的函数没有多大区别,在这个平台上,这些类型具有相同的宽度。这在形式上是非法的,并且几乎可以保证工作正常

甚至可以从
malloc
的定义中推断出所有对象指针都具有相同的表示形式;我可以
malloc
一大块内存,并粘贴任何(C样式)因为
malloc
只返回一个值,但是内存可以被我喜欢的任何对象类型重用,所以很难看到不同的对象指针如何合理地使用不同的表示,除非编译器为每种可能的类型维护一大组值表示映射

void *p = malloc(100000);
foo  *f =  (foo*)p;  *f = some_foo;  
bar  *b =  (bar*)p;  *b = some_bar;
baz  *z =  (baz*)p;  *z = some_baz; 
quux *q =  (quux*)p; *q = some_quux;  
(丑陋的强制转换在C++中是必要的)。以上是需要工作的。因此,虽然我认为正式要求之后
memcmp(f,b)==memcmp(z,q)==memcmp(f,q)==0
,但很难想象一个健全的实现会使这些错误


“不要这样做!< /p> AAAHRG!为什么有人使用这样的代码?”红鼻子独角兽——我不认为这是一个故意的构造。代码被用在网络包处理器中,我猜C++的引用意外通过一个热心的C++开发人员进入这个部分。帮助我删除其中一个我倾向于给你“正确的答案”,因为我喜欢你与malloc的类比,在使用水平上,是我们开发人员决定什么是“正确的”。但是,尽管这在这里和现在都有效,而且你可能是对的,它将在“任何我能接触到的计算机”上工作,我很难在没有证据的情况下相信这样的说法。我认为欧内利说得更可信一点

它完全是偶然的
。它没有被定义为这样实现的,但它是偶然的,而且通常是。。。
void *p = malloc(100000);
foo  *f =  (foo*)p;  *f = some_foo;  
bar  *b =  (bar*)p;  *b = some_bar;
baz  *z =  (baz*)p;  *z = some_baz; 
quux *q =  (quux*)p; *q = some_quux;