编译器无法捕获条件 block 中的变量重新定义

标签 c objective-c gcc compiler-construction llvm

int bar = 2;
if (bar)
{
   int bar;
}

gcc 或 Clang 都无法为此发出警告(或错误),并且程序在启动时立即崩溃。这有充分的理由吗?好像不是什么难抓的东西。这是 block 作用域的基础:嵌套作用域继承封闭 block 的名称...

有什么解释吗?

编辑:原来崩溃是由于使用 Clang。我来回测试了很多次,似乎可以肯定是变量重定义和 Clang 的组合导致了崩溃。但是,我无法在测试项目中重现崩溃,所以去看看吧。

问题原来是与 Objective-C 相关的。正如 Jonathan Leffler 指出的那样,在内部范围内执行“int bar = bar”会从自身初始化变量,这就是导致问题的原因,当初始化是通过 Objective-C 方法调用完成时。

下面显示了正在运行的错误:

-(void)crasher
{
   NSNumber* bar = [NSNumber numberWithInt:2];
   if (bar)
   {
      NSString* bar = [self doit:bar];
   }
}

-(NSString*)doit:(NSNumber*)num
{
   NSString* str = [num stringValue];   // This line causes the crash
   return str;
}

请注意,在纯 C 中做类似的事情不会产生崩溃:

int bar = 2;
if (bar)
{
   char buff[10];
   int bar = sprintf(buff, "%d",bar);       
}

最佳答案

这里没有什么可捕捉的。内部 block 中的变量是一个完全不同的变量,隐藏外部 block 中的变量。这是自古以来就存在的语言的完美标准功能。

您遇到的崩溃与您发布的代码完全无关。除非您在代码中犯了错误,否则在假设您正在使用外部变量的同时使用内部变量。

关于编译器无法捕获条件 block 中的变量重新定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2388475/

相关文章:

c - C 程序错误

linux - Ubuntu/usr/bin/ld : cannot find -lsasl2 while installing monary

ios - 如何交叉编译 GCC 以生成适用于 iOS 设备(arm、armv7)的 libgfortran?

C 覆盖函数的返回地址导致内核 panic

c - 读取一行中的单词并将它们放入数组中

C 以指向字符串的指针作为名称读取文件

ios - UIButton 按下时改变状态

Objective-C:模偏差

c - 即使搜索目录正确,GCC 也无法找到 header

objective-c - 指针和整数 ('int *' 和 'int' 之间的比较)