c++ - 如果 null 不是有效值,则使参数成为引用而不是指针

标签 c++ pointers reference

据我所知,如果参数可以合理地为 null,则类似于函数参数类型的指针应该是一个指针,如果参数永远不会为 null,则它应该是一个引用,这是一个很好的规则.

基于那个“规则”,我天真地期望做类似的事情 someMethodTakingAnIntReference(*aNullPointer) 在尝试调用时会失败,但令我惊讶的是,以下代码运行得很好,这有点让“规则”不太可用。开发人员仍然可以从引用的参数类型中读取含义,但编译器无济于事,运行时错误的位置也无济于事。

我是否误解了这条规则的要点,或者这是未定义的行为,还是...?

int test(int& something1, int& something2)
{
    return something2;
}

int main()
{
    int* i1 = nullptr;
    int* i2 = new int{ 7 };

    //this compiles and runs fine returning 7.
    //I expected the *i1 to cause an error here where test is called
    return test(*i1, *i2); 
}

虽然上面的方法有效,但显然下面的方法无效,但如果引用只是指针,情况也是如此;这意味着规则和编译器并没有真正帮助。

int test(int& something1, int& something2)
{
    return something1+something2;
}

int main()
{
    int* i1 = nullptr;
    int* i2 = new int{ 7 };


    //this compiles and runs returning 7.
    //I expected the *i1 to cause an error here where test is called
    return test(*i1, *i2); 
}

最佳答案

编写 test(*i1, *i2) 导致 undefined behaviour ;特别是 *i1 部分。 [expr.unary.op]/1 在 C++ 标准中对此进行了介绍:

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

这仅针对 X 指向对象或函数的情况定义了 *X 的行为。由于 i1 没有指向对象或函数,标准没有定义 *i1 的行为,因此它是未定义的行为。 (这有时被称为“遗漏未定义”,同样的做法处理许多不指定对象的左值的其他用途)。


如链接页面中所述,未定义的行为不需要任何类型的诊断消息。运行时行为实际上可以是任何东西。编译器可以但不是必须生成编译警告或错误。一般来说,是否遵守语言规则取决于程序员。编译器在一定程度上有所帮助,但不能涵盖所有情况。

关于c++ - 如果 null 不是有效值,则使参数成为引用而不是指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48105175/

相关文章:

c++ - 动态数组-读取

c++ - 全局范围内的对象在程序退出时导致崩溃

c++ - 如何解析 HTTP POST(文件上传)流?

C - 将指向数组的指针传递给函数以打印数组

rust - 为什么不能在同一结构中存储值和对该值的引用?

java - 更改 Java 中的最终字符串值

objective-c - 为什么从容器中获取对象时引用计数没有增加?

c++ - 带有 C++ 生成器的 CUDA

python - 使用 char 指针函数和 std::string 调用线程会产生不同的结果

c - 通过引用传递字符串数组以在 C 中运行和修改内容