2010-11-15 2 views
0

Plusieurs lignes de code valent mille mots:Un autre BUG de VC++ 2010? A propos de la déclaration d'une référence constante dans un en-tête

J'ai trois fichiers simples: header.h, main.cpp, other.cpp

// header.h 

    #pragma once 

inline const int& GetConst() 
{ 
    static int n = 0; 
    return n; 
} 

const int& r = GetConst(); 

// main.cpp 

    #include "header.h" 

int main() 
{ 
    return 0; 
} 

// other.cpp 

    #include "header.h" 

Lors de la compilation le projet le plus simple, le VC++ 2010 se plaint comme suit:

ClCompile: 
    other.cpp 
    main.cpp 
    Generating Code... 
    other.obj : error LNK2005: "int const & const r" ([email protected]@3ABHB) already defined in main.obj 
D:\Test\Debug\bug.exe : fatal error LNK1169: one or more multiply defined symbols found 

Build FAILED. 

Time Elapsed 00:00:00.29 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

Je suis sûr que ce soit un bug de VC++ 2010, en raison des deux références suivantes:

1, La norme C++ dit: (à la page 140 de n3126)

"Les objets déclarés const et non explicitement déclarés extern ont une liaison interne."

2, Le MSDN dit: (à l'adresse: http://msdn.microsoft.com/en-us/library/357syhfh(VS.80).aspx).

« En C, les valeurs constantes par défaut de liaison externe, de sorte qu'ils ne peut apparaître que dans les fichiers source en C++, par défaut des valeurs constantes de liaison interne, leur permet d'apparaître dans les fichiers d'en-tête

Le mot-clé const peut également être utilisé dans les déclarations de pointeurs. "

+1

duplication possible de [Est-ce un BUG de VC++ 2010? A propos de la déclaration d'un objet constant dans un en-tête.] (Http://stackoverflow.com/questions/4185275/is-this-a-bug-of-vc-2010-about-declaring-a-constant-object-in-a -header) –

+1

Ne définissez pas de variables dans votre fichier d'en-tête ('r' dans ce cas). Cela n'a rien à voir avec la constance. Voir la question dup pour le correctif. –

+7

J'adore comment vous supposez qu'il s'agit d'un bug dans un compilateur utilisé par des millions de personnes, et vous ne pouvez pas penser que c'est un bug dans votre compréhension de C++. –

Répondre

10

Le paragraphe que vous citez de la norme C++ lit (C++ 03 7.1.1/6):

objets déclarés et non déclarés const explicitement extern ont une liaison interne.

Vous n'avez pas déclaré d'objet. Vous avez déclaré une référence. Une référence n'est pas un objet. Cela dit, 3,5/3 dit:

Un nom ayant la portée d'espace de noms a une liaison interne si elle est le nom d'un objet ou une référence qui est explicitement déclarée const et ni explicitement déclaré extern ni précédemment déclaré avoir une liaison externe

Cependant, 8.3.2/1 dit:

références Cv-qualifiés sont mal formés

Ainsi, alors qu'une référence const-qualifiée aurait une liaison interne, il n'est pas possible de qualifier une référence.

La référence dans votre exemple de programme n'est pas const-qualified, il s'agit d'une référence à un int const-qualifié.

+0

Merci, James. Votre explication est concise et convaincante! – xmllmx

+3

Alors, acceptez sa réponse, alors :) –