为什么同一声明区域内的同名声明被拒绝?

时间:2014-05-31 17:35:33

标签: c++ language-lawyer

以下代码无法编译:

#include <iostream>
#include <stdio.h>

int a=5;
char a='a';

int main(){ std::cout << a;}

这是因为:

test.cpp:5:6: error: conflicting declaration ‘char a’
test.cpp:4:5: error: ‘a’ has a previous declaration as ‘int a’

但是这个限制在标准中指定了哪里?我找不到它。请给我一个参考。

3 个答案:

答案 0 :(得分:7)

C ++11§3.3.1¶4

  

在单个声明性区域中给出一组声明,每个声明都指定相同的非限定名称,

     
      
  • 他们都应该引用同一个实体,或者全部引用功能和功能模板;或
  •   
  • 只有一个声明应声明一个不是typedef名称的类名或枚举名   其他声明均应引用相同的变量或枚举,或全部引用功能   和功能模板;在这种情况下,隐藏类名或枚举名(3.3.10)。 [注:A   名称空间名称或类模板名称在其声明性区域中必须是唯一的(7.3.2,第14条)。    - 尾注]
  •   

在您的情况下,这些条件都不符合,因此您的程序格式不正确。

答案 1 :(得分:0)

这是对单一定义规则(ODR)的简单违反。见n3797 S3.2 / 1。

  

任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义。

真的没有必要说了。这些行中的每一行都是a定义(不是声明)。该计划格式不正确。

如果这些声明属于不同的翻译单元,则该程序仍然是格式不正确的,但适用的规则是不同的。见S3.5 / 10。

答案 2 :(得分:0)

当前案例中的实际原因是 david.pfx 正确观察到的ODR。 但请考虑以下示例:

#include <iostream>
#include <stdio.h>

extern int a;
extern char a;

int main(){ std::cout << a;}

实际原因并非违反3.3。实际上在13/1中说:

  

为单个指定两个或多个不同声明时   在同一范围内的名称,该名称被称为重载。通过   扩展,声明相同的范围内的两个声明   名称但具有不同类型的名称称为重载声明。只要   函数和函数模板声明可以重载;   变量和类型声明不能重载。

因此,我只是想重载非函数声明。