Je ne peux pas comprendre ceci:
int main() {
int (*) (int *) = 5;
return 0;
}
L'affectation ci-dessus se compile avec g ++ c ++ 11. Je sais que int (*) (int *)
c'est un pointeur vers une fonction qui accepte un (int *)
comme argument et renvoie un int, mais je ne comprends pas comment vous pourriez l'assimiler à 5. Au début, je pensais que c'était une fonction qui renvoie constamment 5 (d'après mon récent apprentissage en F #, probablement, haha), alors j'ai pensé, brièvement, que le pointeur de fonction pointe vers l'emplacement mémoire 5, mais cela ne fonctionne pas, clairement, et les valeurs hexadécimales non plus.
Pensant que cela pourrait être dû au fait que la fonction renvoie un int, et que l'attribution d'un int est ok (en quelque sorte), j'ai également essayé ceci:
int * (*) (int *) = my_ptr
où my_ptr
est de type int *
, du même type que ce deuxième pointeur de fonction, comme dans le premier cas avec le type int. Cela ne compile pas. L'affectation de 5, ou de toute valeur int, au lieu de my_ptr
, ne compile pas non plus pour ce pointeur de fonction.
Alors, que signifie la mission?
Mise à jour 1
Nous avons la confirmation qu'il s'agit d'un bug, comme indiqué dans la meilleure réponse. Cependant, on ne sait toujours pas ce qui arrive réellement à la valeur que vous affectez au pointeur de fonction, ou ce qui se passe avec l'affectation. Toute (bonne) explication à ce sujet serait très appréciée! Veuillez vous référer aux modifications ci-dessous pour plus de clarté sur le problème.
Modifier 1
J'utilise la version 4.8.2 de gcc (dans Ubuntu 4.8.2)
Modifier 2
En fait, l'assimiler à n'importe quoi fonctionne sur mon compilateur. Même l'assimiler à une variable std :: string, ou à un nom de fonction qui renvoie un double, fonctionne.
Modifier 2.1
Fait intéressant, en faire un pointeur de fonction vers n'importe quelle fonction qui renvoie un type de données qui n'est pas un pointeur, le laissera compiler, tel que
std::string (*) () = 5.6;
Mais dès que le pointeur de fonction est sur une fonction qui renvoie un pointeur, il ne se compile pas, comme avec
some_data_type ** (*) () = any_value;
la source
error: expected identifier or '(' before ')' token
int *x = 5
vous l'avez nomméx
. Avecint * (*x) (int *) = 5
elle ne compilera pas. (bien que cela compilera en code C).int(*) = 5;
etint(*);
Réponses:
C'est un bogue dans g ++.
est un nom de type.
En C ++, vous ne pouvez pas avoir de déclaration avec un nom de type sans identificateur.
Donc, cela compile avec g ++.
et cela compile aussi:
mais ce sont toutes deux des déclarations invalides.
MODIFIER :
TC mentionne dans les commentaires bugzilla bug 60680 avec un cas de test similaire
mais il n'a pas encore été approuvé. Le bogue est confirmé dans bugzilla.EDIT2 :
Lorsque les deux déclarations ci-dessus sont à portée de fichier, g ++ émet correctement un diagnostic (il ne parvient pas à émettre le diagnostic à portée de bloc).
EDIT3 :
J'ai vérifié et je peux reproduire le problème sur la dernière version de g ++ version 4 (4.9.2), la dernière pré-version 5 (5.0.1 20150412) et la dernière version expérimentale 6 (6.0.0 20150412).
la source
error C2059: syntax error : ')'
int (*int_func)(int *);
qui déclare un pointeur de fonction nomméint_func
.int x[5];
et pasint[5] x;
Ce n'est pas du C ++ valide. N'oubliez pas que parce que votre compilateur particulier compile, il ne le rend pas valide. Les compilateurs, comme tous les logiciels complexes, ont parfois des bogues et cela semble en être un.
En revanche se
clang++
plaint:C'est le comportement attendu car la ligne incriminée n'est pas C ++ valide. Il prétend être une affectation (à cause de la
=
) mais ne contient aucun identifiant.la source
Comme d'autres réponses l'ont souligné, c'est un bug qui
compile. Une approximation raisonnable de cette affirmation qui devrait avoir un sens est:
Voici maintenant
proc
un pointeur vers une fonction qui s'attend à ce que l'adresse5
soit l'adresse de base d'une fonction qui prend unint*
et retourne unint
.Sur certains microcontrôleurs / microprocesseurs, il
5
peut y avoir une adresse de code valide et il peut être possible d'y localiser une telle fonction.Sur la plupart des ordinateurs à usage général, la première page de mémoire (adresses
0-1023
pour les pages 4K) est volontairement invalide (non mappée) afin de capturernull
accès du pointeur.Ainsi, alors que le comportement dépend de la plate-forme, on peut raisonnablement s'attendre à ce qu'une erreur de page se produise lorsqu'elle
*proc
est invoquée (par exemple,(*proc)(&v)
). Avant l'heure à laquelle*proc
est invoqué, rien d'inhabituel ne se produit.À moins que vous n'écriviez un éditeur de liens dynamique, vous ne devriez certainement pas calculer numériquement les adresses et les affecter à des variables de pointeur vers une fonction.
la source
Cette ligne de commande génère de nombreux fichiers intermédiaires. Le premier d'entre eux
so.cpp.170r.expand
, dit:Cela ne répond toujours pas à ce qui se passe exactement, mais cela devrait être un pas dans la bonne direction.
la source