当我调用函数而不将其返回值分配给变量时会发生什么?
What happens when I call a function without assigning its returned value to a variable?
假设我有以下功能:
int foo()
{
return 1234;
}
调用此函数而不将其返回值赋给任何变量的效果是什么:
foo();
还有使用运算符而不将其返回值分配给任何变量的效果是什么:
1 + 2 + 3;
操作或函数将被评估并将继续运行。根据您的编译器,您可能会看到警告,但它会继续 运行 没有问题。
在 C++ 中,表达式是有效的语句;计算值被简单地丢弃。
有些编译器足够聪明,可以在代码看起来很奇怪时发出警告;例如有:
foo(1,2,3);
可以理解(调用可能有副作用的函数)但是代码像
x < 3;
没有用,因为它没有明确的副作用并且该值被丢弃。
在 g++ 中,还有一些库函数尽管有副作用,但被特别标记,因此忽略 return 值会引发警告(如 fread
),因为它是一个错误的标志等待咬.
还有一些非常常见的情况,其中经常忽略函数的结果(如 printf
),并且 return 值的表达式仅用于副作用(喜欢 std::cout << "Hello";
).
如果您想在 运行 时强制函数的结果没有被静默忽略,有时可以使用一个技巧:
template<typename T>
struct must_check {
T x;
bool checked;
must_chec(const T& x) : x(x), checked(false) {}
operator T () { checked = true; return x; }
~must_check() {
if (!checked)
throw std::runtime_error("Result value has not been checked");
}
};
现在不用写
int square(int x) {
return x * x;
}
随便写
must_check<int> square(int x) {
return x * x;
}
然后像这样编码
square(12);
会在运行时抛出异常,而
int result = square(12);
会很好。
这是可能的,但不是一个好主意,因为在析构函数中抛出异常是一种非常糟糕的行为,通常会导致程序异常终止(原因是有时会自动调用析构函数,因为异常,在该阶段抛出 另一个 异常是致命的一步)。
您不必对 C++ 中函数的返回值执行任何操作。您可以调用函数并简单地忽略返回值。运算符也是函数,因此您可以调用它,然后表达式将被计算并再次计算 - 结果可能会被遗忘。
在底层,当一个函数returns取值时,这个值被复制到eax(在32位机器上)或rax(64位机器)寄存器中,然后调用函数使用eax或rax注册以读取返回的数据。
在这种情况下,调用函数只是不读取 eax/rax 寄存器。
假设我有以下功能:
int foo()
{
return 1234;
}
调用此函数而不将其返回值赋给任何变量的效果是什么:
foo();
还有使用运算符而不将其返回值分配给任何变量的效果是什么:
1 + 2 + 3;
操作或函数将被评估并将继续运行。根据您的编译器,您可能会看到警告,但它会继续 运行 没有问题。
在 C++ 中,表达式是有效的语句;计算值被简单地丢弃。
有些编译器足够聪明,可以在代码看起来很奇怪时发出警告;例如有:
foo(1,2,3);
可以理解(调用可能有副作用的函数)但是代码像
x < 3;
没有用,因为它没有明确的副作用并且该值被丢弃。
在 g++ 中,还有一些库函数尽管有副作用,但被特别标记,因此忽略 return 值会引发警告(如 fread
),因为它是一个错误的标志等待咬.
还有一些非常常见的情况,其中经常忽略函数的结果(如 printf
),并且 return 值的表达式仅用于副作用(喜欢 std::cout << "Hello";
).
如果您想在 运行 时强制函数的结果没有被静默忽略,有时可以使用一个技巧:
template<typename T>
struct must_check {
T x;
bool checked;
must_chec(const T& x) : x(x), checked(false) {}
operator T () { checked = true; return x; }
~must_check() {
if (!checked)
throw std::runtime_error("Result value has not been checked");
}
};
现在不用写
int square(int x) {
return x * x;
}
随便写
must_check<int> square(int x) {
return x * x;
}
然后像这样编码
square(12);
会在运行时抛出异常,而
int result = square(12);
会很好。
这是可能的,但不是一个好主意,因为在析构函数中抛出异常是一种非常糟糕的行为,通常会导致程序异常终止(原因是有时会自动调用析构函数,因为异常,在该阶段抛出 另一个 异常是致命的一步)。
您不必对 C++ 中函数的返回值执行任何操作。您可以调用函数并简单地忽略返回值。运算符也是函数,因此您可以调用它,然后表达式将被计算并再次计算 - 结果可能会被遗忘。
在底层,当一个函数returns取值时,这个值被复制到eax(在32位机器上)或rax(64位机器)寄存器中,然后调用函数使用eax或rax注册以读取返回的数据。 在这种情况下,调用函数只是不读取 eax/rax 寄存器。