C++指针实现传址调用疑问:直接传值为何仍能运行?
问题原因解析
你遇到的这个现象,本质是两种不同的编译器行为导致的,下面分情况给你讲清楚:
情况1:编译器自动调用了标准库的std::swap
你的代码里用到了std::cout,说明你肯定包含了<iostream>头文件。很多C++标准库实现中,<iostream>会间接引入<utility>头文件——而<utility>里恰好定义了标准库的std::swap模板函数:
template<typename T> void swap(T& a, T& b) { T temp = a; a = b; b = temp; }
这个函数接受的是左值引用,直接传x和y完全合法。当你写swap(x, y)时,编译器会在全局作用域和std命名域里找匹配的函数:你自己写的swap(int*, int*)要求传指针,和int类型不匹配;但std::swap的参数int&和你传入的int完美匹配,所以编译器会自动选择调用std::swap。
这种情况下,程序不仅能运行,甚至会正确交换x和y的值。
情况2:编译器启用了宽松的类型转换(非标准行为)
如果你的编译器开了C语言兼容模式(比如GCC用-std=c90或者没指定严格的C++标准),可能会允许把int隐式转换成int*。这时swap(x, y)会把x的值(5)、y的值(10)当成内存地址传入函数。
但这属于未定义行为:
- 函数里的
*a会尝试访问地址为5的内存,这通常是操作系统保护的区域,大概率直接触发程序崩溃(段错误); - 要是运气好没崩溃,操作的也是无关内存,根本不会改变原来的
x和y,只是看起来“正常运行”而已。
严格的C++标准是禁止这种隐式转换的,正常编译应该直接报错。
怎么验证是哪种情况?
你可以把自己写的swap改个名字(比如my_swap),然后调用my_swap(x, y):
- 如果编译器报错,说明之前是调用了
std::swap; - 如果还能编译,那就是编译器允许了非法的类型转换。
另外,建议打开编译器的严格模式(比如GCC用-std=c++17 -Wall -Werror),这种模糊的问题会直接触发编译错误,避免后续踩坑。
内容的提问来源于stack exchange,提问作者py300
相关产品推荐
相关产品推荐

