仅当初始化与声明结合使用时"crosses initialization of variable"

"crosses initialization of variable" only when initialization combined with declaration

本文关键字:crosses initialization variable of 初始化 当初 声明 结合      更新时间:2023-10-16

我已经阅读了有关"跳转到案例标签"错误的问题,但我仍然有一些问题。我在Ubuntu上使用G 4.7。

此代码给出一个错误:

int main() {
  int foo = 1;
  switch(foo) {
  case 1:
    int i = 0;
    i++;
    break;
  case 2:
    i++;
    break;
  }
}

错误是

jump-to-case-label.cpp: In function ‘int main()’:
jump-to-case-label.cpp:8:8: error: jump to case label [-fpermissive]
jump-to-case-label.cpp:5:9: error:   crosses initialization of ‘int i’

但是,此代码编译良好,

int main() {
  int foo = 1;
  switch(foo) {
  case 1:
    int i;
    i = 0;
    i++;
    break;
  case 2:
    i++;
    break;
  }
}

第二代码比第一个代码少吗?我为为什么G 允许它感到困惑。

其次,此问题的解决方案是调整初始化变量。如果初始化变量是一个大对象,并且开关语句在段循环中,那么每次输入范围并保留范围时,构造函数和破坏者是否会被调用,从而导致效率下降?还是编译器将其优化?

即使对象是 int类型,也始终是未定义的行为。请注意,switch陈述的语句并不是什么特别的:这只是一个陈述,人们[Ab-]使用了这种有趣的方式,例如Duff的设备。声明中唯一特殊的是标签可以采用表格default:case <const-integer-expr>:

语句int i;是变量的定义,但没有初始化。因此,变量的初始化均未被封闭。跳过此定义没有比首先更大的问题。当然,在跳到case 1:时,该值会分配,而不是跳到case 2:时,这与switch统计外的代码中发生的情况没有什么不同,如果人们仅定义变量。

首先,编译器决定如何将switch打开到汇编代码。可以是if,也可以作为goto表。另外,如果将变量初始化编写在一起声明,编译器说这是error。在另一种情况下,它将是warning(编译器警告您,但不能抗拒您)。因此,您可以保护自己。只是它调整了编译器选项,其中warnings将是errors。要与switch中的变量正确使用,您必须指定其范围。例如:

switch(i)
{
case 1:
{
  int j = 0;
}
break;
}

ps。对于C ,开关是地狱。

来自C 11:

C.1.5第6条:语句

6.4.2,6.6.4(开关和goto语句)

更改:现在不可能以显式或隐式初始化器跳过声明(除了未输入的整个块除外)

基本原理:初始化器中使用的构造函数可以分配资源,这些资源在离开块时需要取消分配。 允许跳过初始化器将需要复杂的运行时间 分配的确定。此外,任何使用非初始化的 对象可能是一场灾难。使用此简单的编译时间规则,C 确保如果初始化变量处于范围中,则它具有 肯定是初始化的。

对原始功能的影响:语义上定义良好的功能的删除。

来自GCC诊断典礼:

6.57.10诊断布拉格马斯诊断pragmas

GCC允许用户选择性启用或禁用某些类型的某些类型的 诊断,并更改诊断的种类。例如, 项目的政策可能要求所有来源都与-werror编译 但是某些文件可能有例外,允许特定类型的 警告。或者,一个项目可以选择性地启用诊断和 将它们视为错误,具体取决于哪个预处理器宏是 定义。

pss。编译器知道,在您的变量非初始化的代码块中知道这一点。static C/C++ analysis是什么(例如,免费cppcheck)显示您的问题。

在第二种情况下打开警告(-wall)给出:

foo.cpp:15:8: warning: 'i' may be used uninitialized in this function [-Wuninitialized]

跳过初始化是一个错误,但是编译器不会试图在非初始化变量上超越您。

初始化变量内部开关会导致此错误。这是由于许可问题而发生的。尝试在开关之外初始化变量并在开关内分配值。

同一问题适用于C 线程。