简体   繁体   English

通过引用传递参数时的 C++ 类型转换

[英]C++ type casting when passing argument by reference

I have a function foo with an int parameter passed by reference.我有一个 function foo带有一个通过引用传递的int参数。 And I have a variable with uint16_t type.我有一个uint16_t类型的变量。 I use reinterpret_cast and here is the code:我使用reinterpret_cast ,这里是代码:

#include <iostream>
#include <stdint.h>


void foo(int &bar) {
    std::cout << "bar = " << bar << std::endl;
    bar += 10;
}

int main() {
    uint16_t baz = 100;
    uint16_t qux = 200;
    foo(reinterpret_cast<int &>(baz));
    std::cout << "baz = " << baz << ", qux = " << qux << std::endl;
    foo(reinterpret_cast<int &>(qux));
    std::cout << "baz = " << baz << ", qux = " << qux << std::endl;
    return 0;
}

The output is: output 是:

bar = 100
baz = 110, qux = 200
bar = 7209160
baz = 110, qux = 210

My questions are:我的问题是:

  1. Why in the 2nd time calling foo() , it prints a wrong number, but variable qux is eventually correct?为什么在第二次调用foo()时,它打印了一个错误的数字,但变量qux最终是正确的?
  2. What's the correct way to do a type casting when calling a function whose argument is passed by reference?调用参数通过引用传递的 function 时进行类型转换的正确方法是什么?
  1. In your function foo , std::cout is treating a uint16_t argument as an int so it is reading two extra bytes.在您的 function foo中, std::coutuint16_t参数视为int ,因此它正在读取两个额外的字节。 200 in decimal, the value of qux is 0x00C8 in hexadecimal.十进制为 200,十六进制 qux 的值为qux That big long decimal number 7209160 is 0x006E00C8 in hexadecimal.那个大长十进制数 7209160 是十六进制的 0x006E00C8。 Do you see your qux value in that hex string?你在那个十六进制字符串中看到你的qux值了吗? The leading part of that hex string is 0x006E which is in decimal 110, meaning that std::cout is probably also grabbing the baz variable off the stack when it reaches for your qux variable which is only of size uint16_t;该十六进制字符串的前导部分是 0x006E,它是十进制 110,这意味着当 std::cout 到达您的qux变量时,它可能也在从堆栈中抓取baz变量,该变量的大小仅为 uint16_t; it is looking for an int, which is twice that size.它正在寻找一个整数,它是那个大小的两倍。 The variable is eventually correct because the second time it is passed to cout, it is being correctly treated as a uint16_t value.该变量最终是正确的,因为它第二次被传递给 cout,它被正确地视为 uint16_t 值。

  2. The correct way to do type-casting in this scenario is to use static_cast as this cast will tell you if it can make a valid conversion between the two types.在这种情况下进行类型转换的正确方法是使用static_cast ,因为这种转换会告诉您它是否可以在两种类型之间进行有效转换。 In this case, your compilation would fail.在这种情况下,您的编译将失败。 This is in contrast to reinterpret_cast which simply instructs the compiler to treat a sequence of bits as a different type, without any consideration given to type conversion.这与reinterpret_cast不同,后者只是指示编译器将位序列视为不同的类型,而不考虑类型转换。

every time the program has the same results?每次程序都有相同的结果? I translate the 200 and 7209160 to binary, and they are 11001000 and 11011100000000011001000. And they have same low 8 bits.我将 200 和 7209160 转换为二进制,它们是 11001000 和 11011100000000011001000。它们具有相同的低 8 位。 Thus i guess whether it convert to type int has error.因此我猜它转换为 int 类型是否有错误。 This can be verity to use int declare "quz".这可以是使用 int declare "quz" 的真实性。

Your code has undefined behavior (UB), even in the case foo(reinterpret_cast<int &>(baz));您的代码具有未定义的行为 (UB),即使是foo(reinterpret_cast<int &>(baz)); which seems to works (possible output of UB).这似乎有效(可能是UB的output)。

Simpler would be to remove cast and change foo to:更简单的是删除演员并将foo更改为:

void foo(int bar);

If you cannot change foo , then, use intermediate variable:如果您无法更改foo ,则使用中间变量:

uint16_t baz = 100;
uint16_t qux = 200;
int i = baz;
foo(i);
std::cout << "baz = " << baz << ", qux = " << qux << std::endl;
i = qux;
foo(i);
std::cout << "baz = " << baz << ", qux = " << qux << std::endl;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM