Aujourd'hui, je suis tombé sur un morceau de code qui m'a semblé horrifiant. Les morceaux étaient éparpillés dans différents fichiers, j'ai essayé d'écrire le coeur de celui-ci dans un cas de test simple ci-dessous. La base de code est régulièrement analysée avec FlexeLint sur une base quotidienne, mais cette structure est restée dans le code depuis 2004.
Le truc, c'est qu'une fonction implémentée avec un passage de paramètre utilisant des références est appelée comme une fonction avec un passage de paramètre utilisant des pointeurs... en raison d'une conversion de fonction. La structure a fonctionné depuis 2004 sur Irix et maintenant lors de son portage, cela fonctionne effectivement aussi sur Linux/gcc.
Maintenant, ma question. Peut-on faire confiance à cette structure? Je peux comprendre si les constructeurs de compilateurs implémentent le passage par référence comme s'il s'agissait d'un pointeur, mais est-ce fiable? Y a-t-il des risques cachés?
Devrais-je changer le fref(..)
pour utiliser des pointeurs et risquer de casser quelque chose dans le processus?
Qu'en pensez-vous?
Edit
Dans le code réel, à la fois
fptr(..)
etfref(..)
utilisent la mêmestruct
- le code modifié ci-dessous reflète cela mieux.
#include
#include
using namespace std;
// ----------------------------------------
// Ceci sera passé en référence dans fref(..)
struct string_struct {
char str[256];
};
// ----------------------------------------
// Utilisation de pointeur ici!
void fptr(string_struct *str)
{
cout << "fptr: " << str->str << endl;
}
// ----------------------------------------
// Utilisation de référence ici!
void fref(string_struct &str)
{
cout << "fref: " << str.str << endl;
}
// ----------------------------------------
// Cast vers f(const char*) et appel avec un pointeur
void ftest(void (*fin)())
{
string_struct str;
void (*fcall)(void*) = (void(*)(void*))fin;
strcpy(str.str, "Bonjour!");
fcall(&str);
}
// ----------------------------------------
// Passons au test
int main() {
ftest((void (*)())fptr); // test avec fptr qui utilise un pointeur
ftest((void (*)())fref); // test avec fref qui utilise une référence
return 0;
}