【问题标题】:What does int a mean [closed]int a 是什么意思[关闭]
【发布时间】:2014-05-14 06:09:08
【问题描述】:

如标准中指定的int a 属于简单的declaration。其实

simple-declaration:
    decl-specifier-seq_opt init-declarator-list_opt ; //
    attribute-specifier-seq decl-specifier-seq_opt init-declarator-list ;
type-specifier:
    trailing-type-specifier //
    class-specifier
    enum-specifier
trailing-type-specifier:
    simple-type-specifier //
    elaborated-type-specifier
    typename-specifier
    cv-qualifier
simple-type-specifier:
    nested-name-specifieropt type-name
    nested-name-specifier template simple-template-id
    char
    char16_t
    char32_t
    wchar_t
    bool
    short
    int //
    long
    signed
    unsigned
    float
    double
    void
    auto
    decltype-specifier

因此int a 是一个简单的声明。但是如果我们将a 重新声明到与以下相同的范围内:

int a;
int a;

我们有

test.cpp:4:5: error: redefinition of ‘int a’
test.cpp:3:5: error: ‘int a’ previously declared here

那么int a 到底是什么?

【问题讨论】:

  • 标准的哪一部分规定您可以在同一范围内对同一变量执行两次声明?
  • @merlin2011 我认为问题是,是什么让int a; 在这种情况下成为定义。它必须是一个定义才能打破 ODR 规则。
  • @user2357112 我不明白,这种情况下是否适用ODR?
  • 这是一个简单的编程逻辑,如果你想存储整数值,你必须声明一个变量来为此创建一个内存位置。现在该位置由变量“a”标识。所以现在你不能为新的 int 内存位置声明相同的变量。
  • @JitendraPareek 我对这个问题的编程不感兴趣。我想在标准中找到正式的规则。

标签: c++ declaration definition


【解决方案1】:

它们都是语法上有效的声明,但是两者一起违反了one definition rule。编译器检测并报告此违规行为。 (它们既是声明又是定义。)

【讨论】:

  • ODR 适用于定义,而非声明
  • 这些既是声明又是定义。 (答案已更新)
  • 你能参考标准中说int a是定义的部分吗?
  • @Dmitrii 看到 Rakibul Hasan 的回答。
  • 参见 3.1,其中定义了“声明”和“定义”。它甚至给出了int a; 作为定义的示例,并将extern int a; 作为不是定义的声明的示例。
【解决方案2】:

来自标准

A declaration is a definition unless it declares a function without specifying the function’s body

a 不是方法,所以int a 表示声明和定义。如果您在一个翻译单元中多次定义一个名称,则违反了One definition Rule,因此会出现错误。

编辑

为澄清起见,我将整个段落发布:

声明是一个定义,除非它声明一个函数 指定函数的主体(8.4),它包含外部 说明符 (7.1.1) 或链接规范 (27) (7.5) 并且既不是 初始化器也不是函数体,它在 类定义(9.4),它是一个类名声明(9.1),或者它 是 typedef 声明 (7.1.3)、using-declaration (7.3.3) 或 使用指令(7.3.4)。

【讨论】:

  • 您确定这是标准的相关部分吗?我也会期待一些关于类型的东西(struct Foo; 是声明而不是定义)?
  • @juanchopanza 在这里很重要:int a 是一个定义,因此适用 ODR。 +1 以获得最佳答案。
  • @juanchopanza 这只是一段的开头,“除非”子句中还有很多其他内容。
  • @FerdinandBeyer 好吧,孤立地引用实际上是错误的,这就是我问的原因。
【解决方案3】:

这与两个同名的人相同。编译器混淆了引用哪一个。因此,在同一范围内是不允许的。有两个同名的变量会让编译器感到困惑。

【讨论】:

  • 反例是重新声明为 extern int a; extern int a;
【解决方案4】:

我们使用声明声明变量名称和类型以及为它们定义内存。大多数情况下,这两个动作同时发生,也就是说,大多数声明都是定义(如果是变量而不是函数)。因此错误。然而,情况可能并非总是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-16
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 2010-12-29
    相关资源
    最近更新 更多