38 votes

Pourquoi cette "variable externe non définie" ne provoque-t-elle pas une erreur de l'éditeur de liens en C ++17?

J'ai compilé et exécuté le programme suivant dans un compilateur C ++ 17 (Coliru). Dans le programme, j'ai déclaré une variable extern , mais je ne l'ai pas définie . Cependant, le compilateur ne donne pas d' erreur de l'éditeur de liens .

 #include <iostream>

extern int i; // Only declaration

int func() 
{
    if constexpr (true)
        return 0;
    else if (i)
        return i;
    else
        return -1;
}

int main() 
{
    int ret = func();
    std::cout<<"Ret : "<<ret<<std::endl;
}
 

Pourquoi le compilateur ne donne-t-il pas une erreur de l'éditeur de liens?

58voto

StoryTeller Points 6139

Parce que la variable n'est pas utilisée. Vous avez là un constexpr if qui rejette toujours la branche susceptible de l’utiliser.

L'un des points de constexpr if est que la branche mise au rebut n'a même pas besoin d'être compilée, elle doit simplement être bien formée. C'est ainsi que nous pouvons passer des appels à des fonctions membres non existantes dans une branche mise au rebut.

41voto

AndreyT Points 139512

Dans votre cas, la variable est utilisée dans les vieux états seulement. Cependant, même si nous ignorons ce fait, C++ langage de spécification encore stipule explicitement qu' aucun diagnostic n'est requis pour le manque de définitions

3.2 définition de la règle

4 Chaque programme doit contenir exactement une définition de tous les non-inline fonction ou d'une variable qui est odr-utilisé dans ce programme à l'extérieur d'un jeté de déclaration (6.4.1); pas de diagnostic nécessaires.

La spécification du langage comprend qu'un compilateur optimisant pourrait être assez intelligent pour éliminer toutes les odr-les utilisations d'une variable. Dans ce cas, il serait excessif et inutile d'exiger la mise en œuvre de détecter et de signaler le potentiel de RLL violations.

9voto

Rene Points 1855

Parce que le compilateur produit des erreurs de compilation, l’ éditeur de liens génère des erreurs d’ éditeur de liens ...

Non sérieusement:

 if constexpr (true)
 

est toujours vrai, le compilateur ignore donc le reste de la clause if car elle n'est jamais atteinte. Donc, i n'est jamais utilisé.

1voto

Fabio Turati Points 2527

Cela a alrady été répondu, mais si vous êtes intéressé, cppreference.com a exactement cet exemple pour constexpr si:

Constexpr Si

La déclaration qui commence par if constexpr est connu comme le constexpr si l'instruction.

Dans un constexpr si l'instruction, la valeur de la condition doit être contextuellement converti expression constante de type bool. Si la valeur est true, alors l' énoncé-faux sont rejetées (si présent), sinon, énoncé vrai est rejetée.
[...]
Les rebuts de déclaration peut odr-utiliser une variable qui n'est pas défini:

extern int x; // no definition of x required
int f() {
if constexpr (true)
    return 0;
else if (x)
    return x;
else
    return -x;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X