Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
tsalm
> /* ----------- CODE --------------- */ class A { private: static int* _v;
public:
static int* v() { return _v; }
};
void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v ; // <-- Erreur // int* a = (int*) A::v ; <-- OK } /* ---------- END CODE ------------- */
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Y a t-il une solution ?
> /* ----------- CODE --------------- */
class A
{
private:
static int* _v;
public:
static int* v()
{
return _v;
}
};
void _tmain(int argc, _TCHAR* argv[])
{
int* a = A::v ; // <-- Erreur
// int* a = (int*) A::v ; <-- OK
}
/* ---------- END CODE ------------- */
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas :
error LNK2001: symbole externe non résolu "private: static int * A::_v"
(?_v@A@@0PAHA)
> /* ----------- CODE --------------- */ class A { private: static int* _v;
public:
static int* v() { return _v; }
};
void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v ; // <-- Erreur // int* a = (int*) A::v ; <-- OK } /* ---------- END CODE ------------- */
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Y a t-il une solution ?
Mickaël Wolff
tsalm wrote:
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée membre static.
Dans l'en-tete de la classe : extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre : int * A::_v ;
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas :
error LNK2001: symbole externe non résolu "private: static int *
A::_v" (?_v@A@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée
membre static.
Dans l'en-tete de la classe :
extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre :
int * A::_v ;
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée membre static.
Dans l'en-tete de la classe : extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre : int * A::_v ;
Ah ben oui. v() est une fonction, il faut donc l'appeler :
int* a= A::v();
James Kanze
On Aug 5, 10:54 pm, tsalm wrote:
Le code ci-dessous ne veut pas compiler, j'ai une erreur : << impossible de convertir de 'int *(__cdecl *)(void)' en 'int *' >>
Le premier, c'est un pointeur à une fonction. Le deuxième, c'est un pointeur à une donnée. Il n'y a effectivement aucune conversion entre les deux in C++ ; il y a bien des machines où ils n'ont pas la même taille ou la même représentation. (C'est en revanche une extension courante de permettre la conversion avec reinterpret_cast, si la machine le permet.)
/* ----------- CODE --------------- */ class A { private: static int* _v;
public:
static int* v() { return _v; } };
void _tmain(int argc, _TCHAR* argv[])
Tu veux dire : int main( int argc, char** argv ) (ou simplement int main() , vue que tu ne t'en sers pas des paramètres d'invocation).
{ int* a = A::v ; // <-- Erreur
C'est encore un autre problème. D'abord, qu'est-ce que doit signifier A::v ici ? A::v désigne une fonction membre ; il n'y a que deux choses qu'on peut faire avec une fonction membre : l'appeler (A::v() : puisque la fonction est statique, tu n'as pas besoin d'objet), ou en prendre l'adresse (&A::v, ce qui donnerait un pointeur à une fonction membre -- à ne pas confondre avec un pointeur à une fonction -- si la fonction n'était pas statique, mais dans ce cas-ci, donne un pointeur à une fonction normale).
En admettant que c'est l'adresse que tu veux (puisque certains compilateurs permet d'omettre l'opérateur &, comme extension, bien qu'on se démande bien pourquoi), Ce qui te reste, c'est toujours une adresse à une fonction. Qui n'a rien avoir avec l'adresse d'un int (adresse de donnée).
// int* a = (int*) A::v ; <-- OK}
Pas OK. Mais beaucoup de compilateurs acceptera : int* a = (int*) &A::v ; , même si la norme actuelle exige un « diagnostique ». Si tu as réelement besoin de ce genre de conversion (et certaines fonctions dans l'API d'Unix renvoie un pointeur à une fonction dans un void*), il faut quelque chose du genre : int* a ; reinterpret_cast< int* (*&)() >( a ) = &A::v ;
/* ---------- END CODE ------------- */
Par contre, si je cast A::v en (int*). Ca fonctionne.
Pourquoi alors que le type retourné est pourtant bien un "int*" ?
Parce que l'adresse d'une fonction n'est pas l'adresse d'un int. Si tu veux l'int* de la valeur de retour, il faut appeler la fonction : int* a = A::v() ;
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Aug 5, 10:54 pm, tsalm <ts...@free.fr> wrote:
Le code ci-dessous ne veut pas compiler, j'ai une erreur :
<< impossible de convertir de 'int *(__cdecl *)(void)' en 'int *' >>
Le premier, c'est un pointeur à une fonction. Le deuxième, c'est
un pointeur à une donnée. Il n'y a effectivement aucune
conversion entre les deux in C++ ; il y a bien des machines où
ils n'ont pas la même taille ou la même représentation. (C'est
en revanche une extension courante de permettre la conversion
avec reinterpret_cast, si la machine le permet.)
/* ----------- CODE --------------- */
class A
{
private:
static int* _v;
public:
static int* v()
{
return _v;
}
};
void _tmain(int argc, _TCHAR* argv[])
Tu veux dire :
int main( int argc, char** argv )
(ou simplement
int main()
, vue que tu ne t'en sers pas des paramètres d'invocation).
{
int* a = A::v ; // <-- Erreur
C'est encore un autre problème. D'abord, qu'est-ce que doit
signifier A::v ici ? A::v désigne une fonction membre ; il n'y a
que deux choses qu'on peut faire avec une fonction membre :
l'appeler (A::v() : puisque la fonction est statique, tu n'as
pas besoin d'objet), ou en prendre l'adresse (&A::v, ce qui
donnerait un pointeur à une fonction membre -- à ne pas
confondre avec un pointeur à une fonction -- si la fonction
n'était pas statique, mais dans ce cas-ci, donne un pointeur à
une fonction normale).
En admettant que c'est l'adresse que tu veux (puisque certains
compilateurs permet d'omettre l'opérateur &, comme extension,
bien qu'on se démande bien pourquoi), Ce qui te reste, c'est
toujours une adresse à une fonction. Qui n'a rien avoir avec
l'adresse d'un int (adresse de donnée).
// int* a = (int*) A::v ; <-- OK}
Pas OK. Mais beaucoup de compilateurs acceptera :
int* a = (int*) &A::v ;
, même si la norme actuelle exige un « diagnostique ». Si tu as
réelement besoin de ce genre de conversion (et certaines
fonctions dans l'API d'Unix renvoie un pointeur à une fonction
dans un void*), il faut quelque chose du genre :
int* a ;
reinterpret_cast< int* (*&)() >( a ) = &A::v ;
/* ---------- END CODE ------------- */
Par contre, si je cast A::v en (int*). Ca fonctionne.
Pourquoi alors que le type retourné est pourtant bien un
"int*" ?
Parce que l'adresse d'une fonction n'est pas l'adresse d'un int.
Si tu veux l'int* de la valeur de retour, il faut appeler la
fonction :
int* a = A::v() ;
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Le code ci-dessous ne veut pas compiler, j'ai une erreur : << impossible de convertir de 'int *(__cdecl *)(void)' en 'int *' >>
Le premier, c'est un pointeur à une fonction. Le deuxième, c'est un pointeur à une donnée. Il n'y a effectivement aucune conversion entre les deux in C++ ; il y a bien des machines où ils n'ont pas la même taille ou la même représentation. (C'est en revanche une extension courante de permettre la conversion avec reinterpret_cast, si la machine le permet.)
/* ----------- CODE --------------- */ class A { private: static int* _v;
public:
static int* v() { return _v; } };
void _tmain(int argc, _TCHAR* argv[])
Tu veux dire : int main( int argc, char** argv ) (ou simplement int main() , vue que tu ne t'en sers pas des paramètres d'invocation).
{ int* a = A::v ; // <-- Erreur
C'est encore un autre problème. D'abord, qu'est-ce que doit signifier A::v ici ? A::v désigne une fonction membre ; il n'y a que deux choses qu'on peut faire avec une fonction membre : l'appeler (A::v() : puisque la fonction est statique, tu n'as pas besoin d'objet), ou en prendre l'adresse (&A::v, ce qui donnerait un pointeur à une fonction membre -- à ne pas confondre avec un pointeur à une fonction -- si la fonction n'était pas statique, mais dans ce cas-ci, donne un pointeur à une fonction normale).
En admettant que c'est l'adresse que tu veux (puisque certains compilateurs permet d'omettre l'opérateur &, comme extension, bien qu'on se démande bien pourquoi), Ce qui te reste, c'est toujours une adresse à une fonction. Qui n'a rien avoir avec l'adresse d'un int (adresse de donnée).
// int* a = (int*) A::v ; <-- OK}
Pas OK. Mais beaucoup de compilateurs acceptera : int* a = (int*) &A::v ; , même si la norme actuelle exige un « diagnostique ». Si tu as réelement besoin de ce genre de conversion (et certaines fonctions dans l'API d'Unix renvoie un pointeur à une fonction dans un void*), il faut quelque chose du genre : int* a ; reinterpret_cast< int* (*&)() >( a ) = &A::v ;
/* ---------- END CODE ------------- */
Par contre, si je cast A::v en (int*). Ca fonctionne.
Pourquoi alors que le type retourné est pourtant bien un "int*" ?
Parce que l'adresse d'une fonction n'est pas l'adresse d'un int. Si tu veux l'int* de la valeur de retour, il faut appeler la fonction : int* a = A::v() ;
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
tsalm
>> Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée membre static.
Dans l'en-tete de la classe : extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre : int * A::_v ;
Oula (encore). Je penses que tout le monde aura compris que je veux juste récupérer le pointeur sur la variable "int* _v" :-) Désolé pour cette erreur. Et merci pour vos réponse.
Le code correct est donc : /* ========== CODE =========== */ class A { private: static int* _v;
public: static int* v() { return _v; }
};
void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v() ; } /* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage : error LNK2001: symbole externe non résolu "public: static int * A::_v" (?@@2PAHA)
D'avance merci.
>> Oula. Ce code se compile bien, mais le linkage ne passe en fait pas :
error LNK2001: symbole externe non résolu "private: static int *
A::_v" (?_v@A@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée
membre static.
Dans l'en-tete de la classe :
extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre :
int * A::_v ;
Oula (encore).
Je penses que tout le monde aura compris que je veux juste récupérer le
pointeur sur la variable "int* _v" :-)
Désolé pour cette erreur. Et merci pour vos réponse.
Le code correct est donc :
/* ========== CODE =========== */
class A
{
private:
static int* _v;
public:
static int* v()
{
return _v;
}
};
void _tmain(int argc, _TCHAR* argv[])
{
int* a = A::v() ;
}
/* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage :
error LNK2001: symbole externe non résolu "public: static int * A::_v"
(?_v@A@@2PAHA)
>> Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée membre static.
Dans l'en-tete de la classe : extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre : int * A::_v ;
Oula (encore). Je penses que tout le monde aura compris que je veux juste récupérer le pointeur sur la variable "int* _v" :-) Désolé pour cette erreur. Et merci pour vos réponse.
Le code correct est donc : /* ========== CODE =========== */ class A { private: static int* _v;
public: static int* v() { return _v; }
};
void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v() ; } /* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage : error LNK2001: symbole externe non résolu "public: static int * A::_v" (?@@2PAHA)
D'avance merci.
Wykaaa
tsalm a écrit :
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée membre static.
Dans l'en-tete de la classe : extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre : int * A::_v ;
Oula (encore). Je penses que tout le monde aura compris que je veux juste récupérer le pointeur sur la variable "int* _v" :-) Désolé pour cette erreur. Et merci pour vos réponse.
Le code correct est donc : /* ========== CODE =========== */ class A { private: static int* _v;
public: static int* v() { return _v; }
};
void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v() ; } /* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage : error LNK2001: symbole externe non résolu "public: static int * A::_v" (?@@2PAHA)
D'avance merci.
Ben oui, tu n'as pas de définition de A::_v.
Il te faut définir _v en dehors de tout bloc : int* A::_v = ... ;
La déclaration d'un attribut static dans une classe nécessite que tu aies quelque part la définition. Je cite le "Working Draft, Standard for Programming Language C++" du 4 octobre 2008 :
The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class (3.3.6). [ Example: class process { static process* run_chain; static process* running; }; process* process::running = get_main(); process* process::run_chain = running;
tsalm a écrit :
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas :
error LNK2001: symbole externe non résolu "private: static int *
A::_v" (?_v@A@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée
membre static.
Dans l'en-tete de la classe :
extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre :
int * A::_v ;
Oula (encore).
Je penses que tout le monde aura compris que je veux juste récupérer le
pointeur sur la variable "int* _v" :-)
Désolé pour cette erreur. Et merci pour vos réponse.
Le code correct est donc :
/* ========== CODE =========== */
class A
{
private:
static int* _v;
public:
static int* v()
{
return _v;
}
};
void _tmain(int argc, _TCHAR* argv[])
{
int* a = A::v() ;
}
/* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage :
error LNK2001: symbole externe non résolu "public: static int *
A::_v" (?_v@A@@2PAHA)
D'avance merci.
Ben oui, tu n'as pas de définition de A::_v.
Il te faut définir _v en dehors de tout bloc :
int* A::_v = ... ;
La déclaration d'un attribut static dans une classe nécessite que tu
aies quelque part la définition.
Je cite le "Working Draft, Standard for Programming Language C++" du 4
octobre 2008 :
The declaration of a static data member in its class definition is not a
definition and may be of an incomplete
type other than cv-qualified void. The definition for a static data
member shall appear in a namespace
scope enclosing the member’s class definition. In the definition at
namespace scope, the name of the static
data member shall be qualified by its class name using the :: operator.
The initializer expression in the
definition of a static data member is in the scope of its class (3.3.6).
[ Example:
class process {
static process* run_chain;
static process* running;
};
process* process::running = get_main();
process* process::run_chain = running;
Oula. Ce code se compile bien, mais le linkage ne passe en fait pas : error LNK2001: symbole externe non résolu "private: static int * A::_v" (?@@0PAHA)
Il faut que tu indiques au compilateur où doit etre stocké ta donnée membre static.
Dans l'en-tete de la classe : extern int * A::_v ;
Dans l'unité de compilation qui doit accueillir la donnée membre : int * A::_v ;
Oula (encore). Je penses que tout le monde aura compris que je veux juste récupérer le pointeur sur la variable "int* _v" :-) Désolé pour cette erreur. Et merci pour vos réponse.
Le code correct est donc : /* ========== CODE =========== */ class A { private: static int* _v;
public: static int* v() { return _v; }
};
void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v() ; } /* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage : error LNK2001: symbole externe non résolu "public: static int * A::_v" (?@@2PAHA)
D'avance merci.
Ben oui, tu n'as pas de définition de A::_v.
Il te faut définir _v en dehors de tout bloc : int* A::_v = ... ;
La déclaration d'un attribut static dans une classe nécessite que tu aies quelque part la définition. Je cite le "Working Draft, Standard for Programming Language C++" du 4 octobre 2008 :
The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class (3.3.6). [ Example: class process { static process* run_chain; static process* running; }; process* process::running = get_main(); process* process::run_chain = running;
tsalm
>> /* ========== CODE =========== */ class A { private: static int* _v; public: static int* v() { return _v; } }; void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v() ; } /* ======== END CODE ========= */ Qui me retourne cette fois l'erreur de linkage : error LNK2001: symbole externe non résolu "public: static int * A::_v" (?@@2PAHA) D'avance merci.
Ben oui, tu n'as pas de définition de A::_v.
Il te faut définir _v en dehors de tout bloc : int* A::_v = ... ;
La déclaration d'un attribut static dans une classe nécessite que tu aies quelque part la définition.
Merci. Ca fonctionne parfaitement.
>> /* ========== CODE =========== */
class A
{
private:
static int* _v;
public:
static int* v()
{
return _v;
}
};
void _tmain(int argc, _TCHAR* argv[])
{
int* a = A::v() ;
}
/* ======== END CODE ========= */
Qui me retourne cette fois l'erreur de linkage :
error LNK2001: symbole externe non résolu "public: static int *
A::_v" (?_v@A@@2PAHA)
D'avance merci.
Ben oui, tu n'as pas de définition de A::_v.
Il te faut définir _v en dehors de tout bloc :
int* A::_v = ... ;
La déclaration d'un attribut static dans une classe nécessite que tu
aies quelque part la définition.
>> /* ========== CODE =========== */ class A { private: static int* _v; public: static int* v() { return _v; } }; void _tmain(int argc, _TCHAR* argv[]) { int* a = A::v() ; } /* ======== END CODE ========= */ Qui me retourne cette fois l'erreur de linkage : error LNK2001: symbole externe non résolu "public: static int * A::_v" (?@@2PAHA) D'avance merci.
Ben oui, tu n'as pas de définition de A::_v.
Il te faut définir _v en dehors de tout bloc : int* A::_v = ... ;
La déclaration d'un attribut static dans une classe nécessite que tu aies quelque part la définition.
Merci. Ca fonctionne parfaitement.
tsalm
>
void _tmain(int argc, _TCHAR* argv[])
Tu veux dire : int main( int argc, char** argv ) (ou simplement int main() , vue que tu ne t'en sers pas des paramètres d'invocation).
C'est la fonction "main" proposée par défaut par Visual Studio. Mais, si je comprends bien, il y a une différence entre _TCHAR* et char** : http://msdn.microsoft.com/en-us/library/cc842072.aspx
En tout cas, merci pour tes réponses toujours très riches d'enseignements.
>
void _tmain(int argc, _TCHAR* argv[])
Tu veux dire :
int main( int argc, char** argv )
(ou simplement
int main()
, vue que tu ne t'en sers pas des paramètres d'invocation).
C'est la fonction "main" proposée par défaut par Visual Studio.
Mais, si je comprends bien, il y a une différence entre _TCHAR* et char**
:
http://msdn.microsoft.com/en-us/library/cc842072.aspx
En tout cas, merci pour tes réponses toujours très riches d'enseignements.
Tu veux dire : int main( int argc, char** argv ) (ou simplement int main() , vue que tu ne t'en sers pas des paramètres d'invocation).
C'est la fonction "main" proposée par défaut par Visual Studio. Mais, si je comprends bien, il y a une différence entre _TCHAR* et char** : http://msdn.microsoft.com/en-us/library/cc842072.aspx
En tout cas, merci pour tes réponses toujours très riches d'enseignements.