IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

future : has initializer but incomplete type


Sujet :

Langage C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2008
    Messages : 11
    Par défaut future : has initializer but incomplete type
    Je suis programmeur C qui avait aussi utilisé C++ (avant c++11). Je souhaite utiliser c++11 et future, j'ai essayé le petit test qui ne compile pas, je ne comprend pas pourquoi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <future>
    #include <iostream>
     
    void called_from_async() {
      std::cout << "Async call" << std::endl;
    }
     
    int main() {
      //called_from_async launched in a separate thread if possible
      std::future<void> result( std::async(called_from_async));
     
      std::cout << "Message from main." << std::endl;
     
      //ensure that called_from_async is launched synchronously
      //if it wasn't already launched
      result.get();
     
      return 0;
    }
    Je compile avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    g++ -o future.exe future.cpp
    g++ --version :
    g++ (MinGW.org GCC-6.3.0-1) 6.3.0
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    future.cpp: In function 'int main()':
    future.cpp:167:34: error: variable 'std::future<void> result' has initializer but incomplete type
       std::future<void> result( std::async(called_from_async));
                                      ^~~~~
    future.cpp:167:57: error: invalid use of incomplete type 'class std::future<void>'
       std::future<void> result( std::async(called_from_async));
                                                             ^
    In file included from future.cpp:158:0:
    c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<void>'
         class future;
               ^~~~~~
    Merci !

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Dans le message d'erreur, on peut lire :
    future.cpp:167:34: error: variable 'std::future<void> result' has initializer but incomplete type
    [...]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<void>'
         class future;
    Ca qui semble indiquer que tu as accès à la déclaration de la classe future, mais pas à sa définition (c'est ce que signifie incomplete type).
    Pourquoi ? Je ne peux pas dire, je n'ai pas de mingw chez moi. Il y a quoi dans le header ? Faudrait-il ajouter un flag de compilation pour activer cette fonctionnalite?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut,

    Si l'on en croit cppreference:
    1. The class template std::future provides a mechanism to access the result of asynchronous operations.
      çLa classe std::future fournit un mécanisme pour accéder au résultat d'opération asynchrones)
    2. std::future<void> est une spécialisation complète.
    3. le constructeur de future n'accepte aucun paramètre (voire la page constructeur)

    Du (1) et du (2), on peut en déduire que la spécialisation complete pour void est volontairement incomplete (du genre de template <> future;) du fait ... qu'il n'y a aucun résultat à attendre de la part d'une opération void.

    Dit autrement, tu ne peux utiliser std::future qu'avec des opérations non void, vu que c'est prévu ... pour en récupérer le résultat

    Une des adaptations possibles de ton code pourrait être de renvoyer un booléen, qui pourrait -- par exemple -- indiquer la réussite (ou l'échec) de l'opération, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool called_from_async() {
      std::cout << "Async call" << std::endl;
      return true;
    }
    Ce qui te permettra d'instancier un std::future <bool>Par contre, à cause du (3), la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::future<bool> result( std::async(called_from_async));
    provoquera encore une erreur de compilation, par laquelle le compilateur se plaindra de ne pas trouver de consturcteur prenant un paramètre de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::future<std::result_of_t<std::decay_t<Function>(std::decay_t<Args>...)>> [with Args = bool]
    .
    Tu devras donc aussi la modifier en conséquence et lui donner la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::future<bool> result = std::async(called_from_async);
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2008
    Messages : 11
    Par défaut
    Bonjour,
    merci pour la suggestion, mais le résultat est le même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <future>
    #include <iostream>
     
    bool called_from_async() {
      std::cout << "Async call" << std::endl;
      return true;
    }
     
    int main() {
      //called_from_async launched in a separate thread if possible
      std::future<bool> result = std::async(called_from_async);
     
      std::cout << "Message from main." << std::endl;
     
      //ensure that called_from_async is launched synchronously
      //if it wasn't already launched
      result.get();
     
      return 0;
    }
    J'obtiens toujours :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    C:\MinGW>g++ -o future.exe future.cpp
    future.cpp: In function 'int main()':
    future.cpp:168:21: error: variable 'std::future<bool> result' has initializer but incomplete type
       std::future<bool> result = std::async(called_from_async);
                         ^~~~~~
    future.cpp:168:58: error: invalid use of incomplete type 'class std::future<bool>'
       std::future<bool> result = std::async(called_from_async);
                                                              ^
    In file included from future.cpp:158:0:
    c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\future:115:11: note: declaration of 'class std::future<bool>'
         class future;
               ^~~~~~

  5. #5
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    727
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 727
    Par défaut
    Salut.

    Je ne sais pas si g++ compile en C++11 par défaut, mais dans le doute tu peux rajouter le flag -std=c++11. Et tant qu'à faire, rajouter quelques options de vérification d'erreurs : g++ -o future.exe future.cpp -std=c++11 -wall -werror -pedantic (et des flags supplémentaires que les autres intervenants pourront fournir).

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Je vois de ton message d'erreur que tu utilise la version 6.3.0 de Gcc...

    Sauf erreur de ma part (car je ne prétend pas avoir la science infuse ), cette version a pris le parti de travailler en C++98 par défaut et sans indication contraire de ta part. Tu devrais donc effectivement ajouter le flag -std=c++11 (ou mieux encore : -std=c++14 ou -std=cc++17, pour profiter des dernières évolutions )

    Ou, tu peux aussi décider de mettre ta version de MinGW à jour, malgré le risque de devoir compiler toi-même certaines bibliothèques externes, qui n'offrent pas encore de binaire pour la dernière version disponible (je pense -- entre autres -- à Qt, SFML ou boost).

    Si tu télécharge l'installateur que tu trouve sur sourceforge pour MinGW-W64, tu peux choisir la version de Gcc à télécharger. Si tu prend la version 7.x.y ou -- mieux encore -- la version 8.x.y (désolé, je n'ai plus les numéros exacts de version en tête), tu obtiendra une version de Gcc qui supporte C++17 par défaut (mais qui accepte de "redescendre" vers les normes antérieures avec l'option -std ).

    Evidemment, cela nécessitera de compiler toi-même les bibliothèques externes dont tu as besoin. Certaines (comme SFML) utilise CMake pour la configuration, d'autres (comme Qt) posent problème pour certains modules (comme QtWebEngine) et nécessitent une saveur spécifique de Gcc (posix, seh ou dwarf, selon que tu prend le compilateur 32 bits ou 64 bits), et d'autres encore nécessiteront l'utilisation de MSYS2 car la configuration se fait à l'aide des auto-tools (autonconf, autoheader, automake et libtool).

    Cela peut prendre du temps (surtout pour Qt ou boost), mais cela ne représente rien d'insurmontable : j'y suis bien arrivé tout seul
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2008
    Messages : 11
    Par défaut
    Merci pour la suggestion, mais j'avais déjà essayé avec le flag -std=c++11 et le résultat est le même (et pareil pour -std=c++14)
    Par contre si je compile avec -std=c++98 j'ai bien des messages d'erreurs qui me disent qu'il faut C++ 11.
    Les info détaillées sur la version donnent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    C:\MinGW>g++ -v
    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
    Target: mingw32
    Configured with: ../src/gcc-6.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --with-gmp=/mingw --with-mpfr=/mingw --with-mpc=/mingw --with-isl=/mingw --prefix=/mingw --disable-win32-registry --target=mingw32 --with-arch=i586 --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-pkgversion='MinGW.org GCC-6.3.0-1' --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --with-tune=generic --enable-libgomp --disable-libvtv --enable-nls
    Thread model: win32
    gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Ce n'est pas une histoire de version de compilateur ou d'option de norme à passer. Certaines versions de MinGW n'intègrent tout bonnement pas ce qui est relatif aux threads.

    https://github.com/meganz/mingw-std-threads

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Juste!!! Il faut donc choisir explicitement le support POSIX des threads (et sans doute, par la même occasion, SEH ou Dwarf , comme indiqué au sujet de Qt)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/03/2014, 00h04
  2. Réponses: 2
    Dernier message: 09/12/2011, 08h03
  3. has initializer but incomplete type
    Par laflak dans le forum C
    Réponses: 3
    Dernier message: 25/03/2008, 18h05
  4. Réponses: 3
    Dernier message: 23/01/2008, 16h04
  5. has incomplete type,forward declaration of ,
    Par Pragmateek dans le forum C++
    Réponses: 12
    Dernier message: 22/07/2006, 15h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo