当前位置: 首页 > 知识库问答 >
问题:

如何用extern解析一个新声明的多个先前声明?

邹英光
2023-03-14
#include <stdio.h>

static char x = '1';

int main(void)
{
    char x = '2';
    {
        extern char x;
        printf("%c\n", x);
    }
}

这在这个回答中出现了,并且:

  • 在Apple LLVM 9.1.0 CLANG-902-0.39.2中,外部字符xx引用第一个x并打印“1”。
  • GCC 8.2不接受此源文本。,抱怨:“错误:以前声明为'static‘的变量重新声明为'extern'”。

C 2018 6.2.2 4规定:

由于x有两个先验声明,因此以下每个“if”子句的条件为真,第一个用于第一个先验声明,第二个用于第二个先验声明:

  • ……如果前面声明指定了内部或外部链接,则后面声明中标识符的链接与前面声明中指定的链接相同。
  • …如果前面的声明没有指定链接,则标识符具有外部链接。

Clang在这里的行为与使用第一个子句是一致的,这样第三个x就有了内部的联系,引用了与第一个x相同的对象。GCC在这里的行为与使用第二个子句是一致的,这样第三个x就具有外部联动性,而与第一个x相冲突,后者具有内部联动性。

C标准是否给了我们一种方法来解决这些问题中的哪一个应该是这样的?

共有1个答案

罗建弼
2023-03-14

第三个声明,extern char x,应该声明带有外部链接的x,基于C 2018 6.2.2 4,它说:

对于使用存储类说明符extern声明的标识符,在该标识符的前一个声明可见的范围内,如果前一个声明指定了内部或外部链接,则后一个声明中的标识符的链接与前一个声明中指定的链接相同。如果前面的声明不可见,或者前面的声明没有指定链接,那么标识符具有外部链接。

在声明extern char x处,x的第一个声明不可见,因为它已被第二个声明隐藏。因此,它不符合“该标识符的事先声明是可见的”的条件。x的第二个声明是可见的,因此就上段而言,它是“事先声明”。

则违反6.2.2 7,因为第一个x具有内部链接,第三个x具有外部链接:

如果在一个翻译单元内,出现具有内部和外部链接的相同标识符,则该行为未定义。

由于没有违反语法规则或约束,标准不要求C实现报告诊断。由于行为是未定义的,它可能会做任何事情,包括接受此代码并使第三个x引用与第一个x相同的对象。因此,Clang和GCC的行为都没有违反这方面的标准。然而,由于违反了6.2.2 7项,因此最好进行诊断,如果没有诊断,则可以认为是CLANG的缺陷。

 类似资料:
  • 问题内容: 我正在尝试解析方法声明。基本上,我需要获取接收方基本类型()和返回类型(和)的语法节点。该程序包看起来很简单,但是由于某种原因,我没有获得所需的数据(即,字段为nil)。 唯一有用的数据似乎仅在类型为字段的字段中提供, 因此我认为我无法序列化它。 任何帮助,将不胜感激。代码如下: 操场 问题答案: 要获取类型,您需要查看可能是an 或an 的属性。 这里看看这个:

  • 问题内容: 我有一个包含两个类的元素,一个叫做“ rotate”,它将旋转元素360度,另一个叫做“ doublesize”,它将元素放大两倍于其正常大小: 我猜这是行不通的,因为这些类会覆盖彼此的属性? 我知道我可以很容易地在一条CSS规则中做到这一点,例如: 但是我希望能够在可能的情况下分别应用每个类。 问题答案: 我猜这是行不通的,因为这些类会覆盖彼此的属性? 正确。作为级联工作方式的副作用

  • 下面会对C语言、着色器语言ES GLSL、javascript语言和TypeScript语言声明变量的方式进行简单展示,这样可以更方便不同基础读者类比学习。 C语言 着色器语言ES GLSL和C语言有很多相似之处,如果你有一定的C语言基础,对于学习着色器语言也是有一定的帮助的。 // C语言声明一个整形变量并赋值10 int count = 10; // 改变变量值,重新赋值 count=20;

  • 我正在对这些注释使用基本集成测试: 运行测试时,出现以下错误: 该错误是由以下注释引起的:SpringBootTest和DataMongoTest,包括BootstrapWith,如下所示: 我需要继续使用SpringBootTest进行SpringBootTest。WebEnvironment。RANDOM\u端口,但我还需要来自DataMongoTest的嵌入式mongodb 有什么建议吗?

  • 你好,Iam在spring(IntelliJ IDEA终极版)中使用AspectJ风格的AOP时遇到了麻烦。不使用方面时,输出与预期相同。但是当我将方面类受众声明为Bean时,我得到了Macbeth类的NoSuchBeanDefinitionException。 2017年8月27日上午9:38:39 org.springframework.context.annotationconfigappl

  • 着色器语言和C语言、javascript语言一样可以通过关键字const声明一个常量。 着色器语言和其它语言一样,声明一个变量,可以重新赋值,如果通过关键字const声明一个常量,顾名思义是常量,在代码中是不可以更改的。 // 着色器语言定义一个整形常量 const int count = 10; // 定义一个浮点数常量10.0 const float count = 10.0; // 定义一个