2011-10-25 10 views
4

J'utilise gcc version 4.5.0. En utilisant l'exemple simple suivant, je suppose d'obtenir une erreur conversion non valide du double * à Const double *erreur gcc: conversion invalide de double * à const double

#include <iostream> 
using namespace std; 

void foo(const double *a) 
{ 
    cout<<a[0]*2.<<endl; 
} 

int main() 
{ 
    double *a=new double[2]; 
    a[0]=1.; 
    a[1]=2.; 
    foo(a); 
    return 1; 
} 

Pourquoi est-il compilent sans erreurs?

Un contre est la suivante qui est similaire:

#include<iostream> 
using namespace std; 

void foo(const double **a) 
{ 
cout<<a[0][0]*2.<<endl; 
} 


int main() 
{ 
    double **a=new double*[2]; 
    a[0]=new double[2]; 
    a[1]=new double[2]; 
    a[0][0]=1.; 
    foo(a); 
    cout<<a[0][0]<<endl; 
    return 1; 
} 

(solution pour le deuxième exemple: définir foo foo (const double * const * a) Merci à Jack commentaire Edmonds ce qui explique l'erreur. message)

+1

Pourquoi la conversion serait-elle invalide? – luiscubal

+0

Parce que j'obtiens une erreur de conversion dans le cas où un double ** a est utilisé. –

Répondre

8

Généralement, vous êtes autorisé à rendre implicitement les choses "plus constantes" mais pas "moins constantes" en C et C++. Par conséquent, vous êtes autorisé à passer un objet non-const à une fonction qui prend un objet const.

Fondamentalement, le paramètre const dans la déclaration de méthode est le moyen de la fonction de promettre de ne pas modifier le paramètre.

Vous pouvez voir cette question pour plus d'informations: Question about const_cast in c++

+0

Ce que j'ai trouvé étrange, c'est que j'ai reçu ce message d'erreur dans une fonction plus complexe. Même si cette fonction ne manipulait pas le tableau, le compilateur envoyait cette erreur, contrairement à l'exemple simple. Par conséquent, je me demandais quels critères le compilateur utilise. –

+0

Quelle erreur obtenez-vous spécifiquement? –

+0

prog.cpp: 585: 55: erreur: conversion invalide de 'double ***' en 'const double ***' prog.cpp: 585: 55: erreur: initialisation de l'argument 5 de 'void foo (uint, scaling , uint, double, const double ***, double **) ' –

6

Vous pouvez passer un pointeur non-const à une fonction qui prend un pointeur const. Vous ne pouvez pas faire l'inverse parce que cela viole la constance.

4

Vous devez être en mesure d'initialiser un type de données const. Il est bon de passer un double* à un paramètre qui est const double*. De cette façon, vous pouvez faire ce dont vous avez besoin dans l'appelant, mais l'appelé n'est pas autorisé à changer les choses que vous avez dites sont const.

C'est quand vous allez dans l'autre sens que vous obtiendrez des erreurs et des avertissements.

0

La conversion double *-const double * comme type de paramètre est valide, que vous avez eu beaucoup de réponses qui vous indiquent que.

Cependant, il y a un piège étrange que vous avez peut-être déjà vu qui ne compile pas, ce qui pourrait être la cause de votre confusion maintenant. Si vous n'avez pas vu de code similaire qui ne compile pas, vous pouvez sauter cette réponse car cela pourrait vous rendre plus confus que d'aider. J'ajoute seulement le détail supplémentaire au cas où vous pensiez que vous avez vu cela ne fonctionnait pas avant.

Parfois, la propriété const peut être violée en collant un type const dans le CALLER via un pointeur de paramètre de type const qui a moins de constance dans le CALLER. Cela provoque une erreur de compilation qui, à première vue, ressemble au même type de conversion que vous avez faite. Par exemple, si vous aviez la fonction void bar(const double **a) et l'appeliez avec foo(&a) dans votre main, vous obtiendriez une erreur de compilation même si elle semble être une autre situation où il semble que vous faites un type plus constant.

Voir ce question pour plus de détails sur cette situation.

Questions connexes