if 语句中定义的局部变量行为异常
Local variable definied in an if statement hehaves unexpectedly
最初我想将一堆语句打包成一行,这样我的东西就可以用作 if 中的简单宏。
我需要做 3 件事:
- 创建局部变量
- 用一个函数更新它
- 检查更新后的变量是否与其他变量匹配
这是我的快速草稿代码:
#include <iostream>
#include <stdint.h>
#define MAGIC_VALUE 42
bool MyMockedFunction(uint64_t* outElement)
{
*outElement = MAGIC_VALUE;
return true;
}
static const uint64_t global_should_match_this = MAGIC_VALUE;
int main()
{
// Originally I wanted to declare the variable in one single line (as a defined macro, which should be used in an IF statement)
// That's why I have so many things packed into the same line
// It may or may not (latter is more probable) a good idea, but that's not the question here
if (uint64_t generatedElement = 123456 && MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// I would expect generatedElement == MAGIC_VALUE
printf("Inside value: %llu\n", generatedElement);
}
else
{
printf("Unmatched\n");
}
return 0;
}
我知道以编程方式它可能不是万无一失的,如果我把它放在宏中(宏也是邪恶的),它很容易被滥用,但在我的情况下,这将是一个非常受控的环境,只是为了让我的代码更容易阅读。
那么,问题来了——为什么在运行之后generatedElement等于1?这在任何方面都是未定义的行为吗?
我在编译器反汇编程序中检查过它是 1,因为最终比较的值(表达式是否为真?是 -> 1 -> 这就是移入变量的内容。但对我来说它看起来不合理。为什么编译器会这样做?:O 在 MSVC 和 GCC 上都检查过,两者都产生相同的输出。
你的条件真的是:
uint64_t generatedElement = (123456 && MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
这意味着您使用 布尔结果 初始化 generatedElement
。当您使用 未初始化(和不确定的)值 generatedElement
.
时,还会导致 未定义的行为
如果您的编译器支持 if
statements with initializer(C++17 中的新功能),那么您可以
if (uint64_t generatedElement = 123456; MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// ...
}
否则你必须拆分成单独的变量定义和条件:
uint64_t generatedElement = 123456;
if (MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// ...
}
最初我想将一堆语句打包成一行,这样我的东西就可以用作 if 中的简单宏。 我需要做 3 件事:
- 创建局部变量
- 用一个函数更新它
- 检查更新后的变量是否与其他变量匹配
这是我的快速草稿代码:
#include <iostream>
#include <stdint.h>
#define MAGIC_VALUE 42
bool MyMockedFunction(uint64_t* outElement)
{
*outElement = MAGIC_VALUE;
return true;
}
static const uint64_t global_should_match_this = MAGIC_VALUE;
int main()
{
// Originally I wanted to declare the variable in one single line (as a defined macro, which should be used in an IF statement)
// That's why I have so many things packed into the same line
// It may or may not (latter is more probable) a good idea, but that's not the question here
if (uint64_t generatedElement = 123456 && MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// I would expect generatedElement == MAGIC_VALUE
printf("Inside value: %llu\n", generatedElement);
}
else
{
printf("Unmatched\n");
}
return 0;
}
我知道以编程方式它可能不是万无一失的,如果我把它放在宏中(宏也是邪恶的),它很容易被滥用,但在我的情况下,这将是一个非常受控的环境,只是为了让我的代码更容易阅读。
那么,问题来了——为什么在运行之后generatedElement等于1?这在任何方面都是未定义的行为吗?
我在编译器反汇编程序中检查过它是 1,因为最终比较的值(表达式是否为真?是 -> 1 -> 这就是移入变量的内容。但对我来说它看起来不合理。为什么编译器会这样做?:O 在 MSVC 和 GCC 上都检查过,两者都产生相同的输出。
你的条件真的是:
uint64_t generatedElement = (123456 && MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
这意味着您使用 布尔结果 初始化 generatedElement
。当您使用 未初始化(和不确定的)值 generatedElement
.
如果您的编译器支持 if
statements with initializer(C++17 中的新功能),那么您可以
if (uint64_t generatedElement = 123456; MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// ...
}
否则你必须拆分成单独的变量定义和条件:
uint64_t generatedElement = 123456;
if (MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// ...
}