c++ 编译器如何处理条件中声明的类型?

Posted

技术标签:

【中文标题】c++ 编译器如何处理条件中声明的类型?【英文标题】:How does the c++ compiler handle types declared inside conditionals? 【发布时间】:2014-10-08 17:58:35 【问题描述】:

例如:

if ((rand() % 100) < 50)
    string value = "123";
else
    int value = 123;

编译器是否知道 value 可以有两种可能的类型?这在内部是如何表示的?

【问题讨论】:

它没有。任何计算为零的都是假的,其他的都是真的。 juanchopanza,必须在运行时评估的条件呢? 他们得到评估,如果他们不是 0,他们就是真的。 谷歌programming scope 【参考方案1】:

就编译器而言,这与:

if ((rand() % 100) < 50)
    string aaa = "123";
else
    int bbb = 123;

即您在两个不同的范围内使用相同的名称这一事实完全无关紧要。

如果条件为真,编译器在堆栈上创建一个string,否则它在堆栈上创建一个int。你在源代码中给这些对象起的名字是无关紧要的。

有两种不同的对象,有两种不同的类型,但在运行时创建哪一种取决于条件。

在进入函数时,编译器将为stringint 中较大的一个保留足够的堆栈空间,然后在运行时在该内存位置初始化一个字符串或一个int,如果sizeof(string) != sizeof(int) 然后一些保留的堆栈空间将在某些执行中未使用。

【讨论】:

【参考方案2】:

这并没有声明一个变量的类型在运行时确定(或神奇地具有两种类型),而是实际上是两个独立变量,每个变量都有自己的静态类型和受限于其范围的生命周期.

每个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

编译器不关心变量名,它们只为人类程序员提供信息。这里没有名称冲突,变量也可以命名不同。

【讨论】:

【参考方案3】:

编译器将为 2 个分支考虑 2 个不同的范围。如果您尝试在分支之外使用“value”,而之前没有声明它会引发错误。 (未定义的标识符)

如果你不在每个分支上用“value”做一些东西,你的构造就没有意义。

例如,如果你这样做:

int value = 10;
value = 5;

if ((rand() % 100) < 50)
    string value = "123"
else
    int value = 123

printf("%d\n", value);

它将输入 5。

【讨论】:

以上是关于c++ 编译器如何处理条件中声明的类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理C++编译webrtc无法成功获取sdp的问题?

如何处理C++编译webrtc无法成功获取sdp的问题?

C++ 到 C# 移植问题:我将如何处理具有 double* 作为参数的方法?

如何处理`使用未声明的标识符'UIDevice'`

如何处理构造函数的失败?

如何处理具有完全不同构建系统的第三方库?