Pourquoi les mêmes variables locales externes nommées dans différents blocs obtiennent des liens différents entre les compilateurs en c ++?

12

Pendant que je vérifiais simplement quels liens sont accordés aux variables locales externes,
j'ai constaté que certains comportements différents entre les compilateurs

par exemple, si j'ai testé le code ci-dessous
comme vous le voyez dans les commentaires, les variables varont des liens différents

// foo.cpp
int var = 10;                // external linkage

// main.cpp
#include <iostream>

static int var = 100;        // internal linkage

int main() {
    extern int var;          // internal linkage
    std::cout << var << std::endl;
    {
        extern int var;      // g++: external linkage , clang++: internal linkage
        std::cout << var << std::endl;
        {
            extern int var;  // g++: external linkage , clang++: internal linkage
            std::cout << var << std::endl;
        }
    }
}       

le résultat est

  • g ++: "100 10 10"
  • clang ++: "100 100 100" (msvc ++)

Je peux voir d'après le résultat que s'il y a plus de deux blocs imbriqués,
g ++ accorde simplement des liens externes aux variables

J'ai pu trouver une phrase connexe dans la norme
mais elle n'est toujours pas claire car son comportement est différent selon les compilateurs
( https://eel.is/c++draft/basic.link#6 )

J'ai peur que mon anglais soit mauvais, donc je ne peux pas le comprendre correctement.
Si quelqu'un a une idée de quels compilateurs sont bien conformes à la norme
et si possible quelqu'un pourrait-il élaborer ce que la norme dit exactement pour moi?

hyuk myeong
la source
1
Related stackoverflow.com/questions/41978949/… Je crois que c'est un bogue gcc, la norme donne l'exemple avec f()fonction et le plus extern void f()interne a une liaison interne - vardevrait également avoir une liaison interne, car elle fait référence à la même "entité".
KamilCuk
Les déclarations de portée de bloc de l'OMI d'entités avec une liaison externe sont mauvaises et le langage serait préférable de les interdire
MM
@MM: les unités de module le font!
Davis Herring

Réponses:

4

C'est le sujet du numéro ouvert CWG1839 . L' intention actuelle est que le comportement de Clang et MSVC soit correct.

Davis Herring
la source