例如:
if ((rand() % 100) < 50)
string value = "123";
else
int value = 123;
编译器是否知道该值可以有两种可能的类型?这在内部如何表现?
答案 0 :(得分:4)
就编译器而言,这与:
没有什么不同if ((rand() % 100) < 50)
string aaa = "123";
else
int bbb = 123;
即。你在两个不同的范围内使用相同名称这一事实完全无关紧要。
如果条件为真,编译器会在堆栈上创建string
,否则会在堆栈上创建int
。您在源代码中为这些对象提供的名称无关紧要。
有两个不同的对象,有两种不同的类型,但在运行时创建的对象取决于条件。
在进入函数时,编译器将为较大的string
和int
保留足够的堆栈空间,然后在运行时初始化该内存位置的字符串或int,如果{{ 1}}然后在某些执行中将不使用某些保留的堆栈空间。
答案 1 :(得分:3)
编译器将考虑2个分支的2个不同范围。如果您尝试在分支之外使用“值”,而不先前声明它将导致错误。 (未定义的标识符)
如果你不在每个分支上使用“ value ”创建一些东西,你的构造就没有意义。
例如,如果您执行以下操作:
int value = 10;
value = 5;
if ((rand() % 100) < 50)
string value = "123"
else
int value = 123
printf("%d\n", value);
它会输入5。
答案 2 :(得分:3)
这并没有声明一个变量具有在运行时确定的类型(或者神奇地具有两种类型),但实际上是两个独立变量,每个变量都有自己的静态类型和限制在其范围内的生命周期
每个value
仅在其自己的范围内存活,如果添加大括号则会更清晰
if ((rand() % 100) < 50) {
string value = "123";
// 'value' refers to the string
}
else {
int value = 123;
// 'value' refers to the integer
}
// neither 'value' is alive here
编译器不关心变量名,它们仅用于人类程序员的信息。这里没有名称冲突,变量也可以用不同的名称命名。