如何解决多个先前的声明

如何解决多个先前的声明

本文介绍了对于带有extern的新声明,如何解决多个先前的声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第三个x在其中应指什么:

What should the third x refer to in:

#include <stdio.h>

static char x = '1';

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

此问题出现在此答案中,并且:

This arose in this answer, and:

  • 在Apple LLVM 9.1.0 clang-902-0.39.2中,extern char xx引用第一个x,并打印"1".
  • GCC 8.2不接受该源文本.,抱怨道:错误:变量先前声明为'静态"重新声明为外部"".
  • In Apple LLVM 9.1.0 clang-902-0.39.2, the x of extern char x refers to the first x, and "1" is printed.
  • GCC 8.2 does not accept this source text., complaining: "error: variable previously declared 'static' redeclared 'extern'".

C 2018 6.2.2 4说:

C 2018 6.2.2 4 says:

由于有两个x的在先声明,因此以下每个"if"子句的条件为true,第一个用于第一个在先声明,第二个用于第二个在先声明:

Since there are two prior declarations of x, the condition of each of the following "if" clauses is true, the first for the first prior declaration, and the second for the second prior declaration:

  • …如果在先声明指定内部或外部链接,则在后一个声明中标识符的链接与在先声明中指定的链接相同.
  • …如果先前声明未指定任何链接,则标识符具有外部链接.

这里的Clang行为与使用第一个子句是一致的,因此第三个x具有内部链接,并且与第一个x引用相同的对象. GCC在这里的行为与使用第二个子句是一致的,因此第三个x具有外部链接,并且与第一个x具有内部链接冲突.

Clang’s behavior here is consistent with using the first clause, so that the third x has internal linkage and refers to the same object as the first x. GCC’s behavior here is consistent with using the second clause, so that the third x has external linkage and conflicts with the first x, which has internal linkage.

C标准是否为我们提供了一种方法来解决其中的一种情况?

Does the C standard give us a way to resolve which of these should be the case?

推荐答案

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

The third declaration, extern char x, should declare x with external linkage, based on C 2018 6.2.2 4, which says:

在声明extern char x处,x的第一个声明不可见,因为它已被第二个声明隐藏.因此,它不符合该标识符的先前声明可见"的条件. x的第二个声明是可见的,因此对于上一段而言,它是先前的声明".

At the declaration extern char x, the first declaration of x is not visible, as it has been hidden by the second declaration. Therefore, it does not qualify for "a prior declaration of that identifier is visible." The second declaration of x is visible, so it is a "prior declaration" for the purposes of the above paragraph.

然后,最后一句话应该控制:先前的声明未指定任何链接(6.2.2 6,没有extern的块范围标识符没有链接),因此第三个x具有外部链接.

Then the last sentence should control: The prior declaration specifies no linkage (6.2.2 6, a block-scope identifier without extern has no linkage), so the third x has external linkage.

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

Then 6.2.2 7 is violated because the first x has internal linkage and the third x has external linkage:

由于没有违反语法规则或约束,因此标准不需要C实现来报告诊断.由于行为是不确定的,因此它可以执行任何操作,包括接受此代码并使第三个x引用与第一个x相同的对象.因此,在这方面,Clang和GCC的行为均未违反标准.但是,由于违反了6.2.2 7的要求,因此诊断可能是更可取的选择,而缺少该诊断程序可能会导致Clang的缺陷.

Since no syntax rule or constraint is violated, the C implementation is not required by the standard to report a diagnostic. Since the behavior is undefined, it may do anything, including accept this code and make the third x refer to the same object as the first x. Therefore, neither Clang nor GCC’s behaviors violate the standard in this regard. However, since 6.2.2 7 is violated, a diagnostic may be preferred, and its absence could be consider a defect of Clang.

(向 Paul Ogilvie 和用他们的评论告知了我对此的想法.)

(Credit to Paul Ogilvie and T.C. for informing my thinking on this with their comments.)

这篇关于对于带有extern的新声明,如何解决多个先前的声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 14:31