void * peut-il être utilisé pour stocker des pointeurs de fonction?

void * est défini de manière à pouvoir pointer n’importe quoi. Alors peut-il être utilisé pour pointer une fonction (int send ())?

int send(); void* p = send; 

C’est possible? Quand j’utilise comme ça ça ne me montre pas les erreurs pourquoi? Sinon, y a-t-il un moyen de stocker tous les pointeurs dans une seule variable?

Non, il se peut que non.

Selon la norme C (6.3.2.3 Pointeurs)

1 Un pointeur sur void peut être converti en ou à partir d’un pointeur en n’importe quel type d’object . Un pointeur sur n’importe quel type d’object peut être converti en un pointeur à annuler et inverser; le résultat doit être égal au pointeur d’origine.

Comme pour les pointeurs de fonction puis

8 Un pointeur sur une fonction d’un type peut être converti en un pointeur sur une fonction d’un autre type et inversement; le résultat doit être égal au pointeur d’origine. Si un pointeur converti est utilisé pour appeler une fonction dont le type n’est pas compatible avec le type référencé, le comportement est indéfini.

La norme C ++ contient une définition plus détaillée des pointeurs (3.9.2 Types composés)

3 Le type d’ un pointeur sur void ou d’un pointeur sur un type d’object est appelé un type de pointeur d’object …. Le type d’un pointeur pouvant désigner une fonction est appelé un type de pointeur de fonction .

Et

4 Un pointeur sur un vide qualifié cv (3.9.3) ou un vide non qualifié peut être utilisé pour pointer sur un object de type inconnu. Un tel pointeur doit pouvoir contenir n’importe quel pointeur d’object. Un object de type cv void * doit avoir les mêmes exigences de représentation et d’alignement que cv char *.

Peut être. Jusqu’en C ++ 11, ils ne pouvaient pas; mais C ++ 11 ajoute:

La conversion d’un pointeur de fonction en un type de pointeur d’object ou inversement est prise en charge de manière conditionnelle. La signification d’une telle conversion est définie par l’implémentation, sauf que si une implémentation prend en charge les conversions dans les deux sens, la conversion d’une prvalue d’un type en un autre type et inversement, éventuellement avec une cvqualification différente, donnera la valeur de pointeur d’origine.

Cela ne semble pas l’avoir fait pour le moment.

La raison pour laquelle vous ne pouvez pas convertir entre eux, bien sûr, est parce qu’ils peuvent ne pas avoir la même taille ou le même format. Posix exige qu’ils aient la même taille et le même format, et je m’attendrais à ce que tous les compilateurs Posix prennent en charge la conversion. la plupart le faisaient avant de toute façon, même si cela les rendait non conformes.

MODIFIER:

Un peu plus d’informations. Après avoir relu le standard C, je pense que les conversions entre les pointeurs d’object et les pointeurs de fonction constituent un comportement indéfini: le standard C ne semble pas nécessiter de diagnostic dans ce cas, mais il n’en définit aucun comportement. En tant que comportement indéfini, une implémentation (ou Posix) est libre de le définir. Ou tout simplement faire ce qu’il veut, sans le documenter.

D’autre part, C ++, avant C ++ 11, nécessitait un diagnostic (bien qu’un certain nombre de compilateurs n’en aient pas donné un). En C ++ 11, conformément au paragraphe cité ci-dessus, il est défini par l’implémentation si une implémentation le supporte ou non, et si une implémentation le prend en charge, ils doivent documenter son comportement. Donc, dans tous les cas, une implémentation est nécessaire pour documenter ce qu’elle fait et, si elle ne le prend pas en charge, il est nécessaire d’émettre un diagnostic si le code tente d’effectuer la conversion.