Demat'iNal,
La ligne suivante est valide en ANSI C, sauras-tu l'analyser mentalement et en décrire les effets ?
int a, * const b, (*(c(void)))[10], *d[2] = {&a};
Demat'iNal,
La ligne suivante est valide en ANSI C, sauras-tu l'analyser mentalement et en décrire les effets ?
int a, * const b, (*(c(void)))[10], *d[2] = {&a};
# 100% collègue
Posté par devnewton 🍺 (site web personnel) . Évalué à 10.
Le premier effet de ce code sera de faire écrire un commentaire ou un ticket par un collègue pour demander ce que tu as voulu faire et si tu peux le réécrire de façon lisible.
Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.
[^] # Re: 100% collègue
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 4.
J’allais écrire « un commentaire dans la MR pour réécrire ce code (ou au moins mettre l’explication en commentaire si le code est légitime) », et donc je te rejoins.
La connaissance libre : https://zestedesavoir.com
# Non
Posté par Serge Julien . Évalué à 6.
…du moins pas avant mon quatorzième café!
Ça fait 35 ans que je n'ai plus fait de C. Je ne sais pas si cette ligne était valide à cette époque-là, mais dans l'affirmative, elle était déjà aussi illisible.
# Je tente
Posté par Julien Jorge (site web personnel) . Évalué à 10.
a
est un entier de valeur indéterminée.b
est un pointeur constant vers un entier, l'adresse pointée est, heu…, indéterminée mais fixe ?c
est, heu…, un tableau de 10 pointeurs non initialisés de fonctions sans paramètres qui retournent un pointeur vers un entier.d
est un tableau de deux pointeurs sur entiers, le premier est l'adresse dea
et le second est null.J'ai bon ? C'est pas facile de tête sur téléphone en vacances :)
[^] # Re: Je tente
Posté par Clément V . Évalué à 3.
Je dirais plutôt une fonction sans paramètres qui retourne un pointeur vers un tableau de 10 entiers.
[^] # Re: Je tente
Posté par nud . Évalué à 4.
je dirais même un pointeur vers une fonction qui retourne un pointeur vers un tableau de 10 entiers ;-)
[^] # Re: Je tente
Posté par David Demelier (site web personnel) . Évalué à 4.
Petite astuce, cdecl
git is great because linus did it, mercurial is better because he didn't
# sans tricher
Posté par jseb . Évalué à 10. Dernière modification le 11 août 2023 à 10:35.
Bon sans tricher (j'ai pas demandé à chatToutPété ni à internet, et je n'ai pas lu les autres réponses avant de taper celle-ci)
int a : bon ok. Je ne pense pas que ce soit un piege.
*const b : pointeur a constant nommé b.
(*(c(void)))[10] : tableau de 10 pointeurs de fonction 'c' sans paramètre, retournants un entier.
*d[2] = {&a} : tableau d (2 éléments) de pointeurs int initialisés avec l'adresse a qui est indéfinie à ce stade.
Et maintenant, laissez moi vous dire:
LES GENS COMME VOUS, ON DEVRAIT FAIRE DES EXPÉRIENCES DESSUS !
Discussions en français sur la création de jeux videos : IRC libera / #gamedev-fr
[^] # Re: sans tricher
Posté par moi1392 . Évalué à 4. Dernière modification le 11 août 2023 à 10:58.
juste 2 remarques
Si je ne dit pas de bêtises, en C, les paramètres des fonctions n'ont pas besoin d'être déclarés dans les pointeurs sur les fonctions.
D'ailleurs, à l'inverse du C++, les paramètres de fonctions ne sont pas manglés avec le nom de la fonction dans la table des symboles (c'est ce qui permet la surcharge de fonctions en C++ et pas en C)
elle est indéfinie mais représente la première variable locale si on est dans le corps d'une fonction. Du coup indirectement on peut modifier la valeur du pointeur "b" qui est déclaré constant par exemple comme cela :
et hop, b pointe maintenant sur a lui aussi ;)
à priori ça marche aussi si on est pas dans une fonction, c'est juste pas une adresse de la pile mais dans la zone des variables globales du binaire. (.bss s'il me reste des souvenirs en état, mais là vraiment faut aller vérifier, c'est plus de mon âge ces conneries)
Et dans ce dernier cas, le linker devrait pouvoir la déterminer et la fixer sans avoir besoin de code dynamique si on compile un exécutable et pas une librairie.
[^] # Re: sans tricher
Posté par SChauveau . Évalué à 3.
C'est en effet possible avec une liste de paramètres vides '()' mais ici le '(void)' implique une fonction sans aucuns paramètres.
Le premier élément de d est effectivement initialisé avec l'adresse de a mais le second est initialisé à 0.
En fait, non. Le compilateur n'a aucune obligation de conserver l'ordre des variables locales ou globales. Pour les variables locales (ou static), il n'est même pas obligé de leur affecter une adresse sauf si cette adresse est utilisée dans le code (par exemple avec &b). En pratique, la variable b peut très bien exister dans un registre ou ne pas exister du tout. Pour les variables globales, la situation est encore plus complexe car les elles sont typiquement rangées dans des zone mémoires différentes en fonction de leur nature (read-only, read-write, initialisé avec des 0, …). Le compilateur peut aussi décider de réordonner les variables pour diverses raisons (alignements, tailles, optimisations, …)
[^] # Re: sans tricher
Posté par Julien Jorge (site web personnel) . Évalué à 3.
J'allais le dire ! La direction de la pile n'est pas spécifiée dans le standard si je me souviens bien. En plus des arguments que tu as listé.
Mais ce
int* const b
non initialisé m'embête. Je suis surpris que ça compile.[^] # Re: sans tricher
Posté par moi1392 . Évalué à 3.
En effet j'ai allègrement zappé la phase d'optimistion du compilateur et du linker ;)
Ça doit être parce que je debug… sur des builds compilés en debug et qu'il m'est arrivé de voir de genre de dépassement et de constater l'écrasement des variables adjacentes ;)
# Les femmes aiment compiler le C
Posté par gUI (Mastodon) . Évalué à 10.
Et si par hasard il y en a qui ne connaissent pas les concours d'obscurcissement de C, voici le lien indispensable !
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Les femmes aiment compiler le C
Posté par steph1978 . Évalué à 3.
Il n'y a pas eu d'édition depuis 2020 ?
[^] # Re: Les femmes aiment compiler le C
Posté par Psychofox (Mastodon) . Évalué à 10.
Les gens de plus de 50 ans sont tous morts de la Covid en 2020.
[^] # Re: Les femmes aiment compiler le C
Posté par abriotde (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 12 août 2023 à 22:06.
IL y a vraiment des trucs incroyable. Il faut que cela tienne sur un nombre limité de caractères (Pas nombreux), et une des astuces, c'est qu’énormément de valeurs sont passées dans le ligne de compilation. Alors évidemment ils l'écrivent en C normal et obscurcissent pour l'épreuve. Mais il y a souvent en plus énormément d'astuce pour limiter le nombre d'instruction.
Je me souvient
d'un simulateur de vol présenté sous la forme d'un avion en ASCII Art. (Il se joue sur console en ascii art)
Un tableur excel très complet. Qui s'utilise en console.
Bref je trouve se concours inutile mais très passionnant.
Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.
# gépéto
Posté par steph1978 . Évalué à 2.
Cette ligne de code déclare plusieurs variables en C :
int a
: déclare une variablea
de type entier.* const b
: déclare un pointeur constantb
qui pointe vers une valeur de type indéterminé.(*(c(void)))[10]
: déclare un tableau de pointeurs de taille 10, où chaque élément est un pointeur vers une fonctionc
qui ne prend pas d'arguments et renvoie un pointeur.*d[2] = {&a}
: déclare un tableau de pointeursd
de taille 2, où chaque élément est un pointeur vers un entier. Le premier élément du tableaud
est initialisé avec l'adresse de la variablea
.En résumé, la ligne de code déclare une variable entière
a
, un pointeur constantb
, un tableau de pointeurs de fonctionsc
, et un tableau de pointeurs d'entiersd
initialisé avec l'adresse dea
.# La syntaxe au sens équivalente n'est pas
Posté par YetiBarBar . Évalué à 4.
Syntaxiquement, ça compile (peut-être, j'ai pas testé…).
Et comme avec tout langage (du C, du Python, du rust, du français), on peut balancer des mots qui n'ont ni queue ni tête et chercher le sens à tout ça…
Pour moi, un tel code ne mérite pas de vivre car il n'exprime aucun sens (d'autant que j'entrevois quelques bouts de "UB" qui vont être compilo-dépendant).
# Éléments de réponses
Posté par serge_sans_paille (site web personnel) . Évalué à 7.
Il n'y a pas d'undefined behavior dans l'exemple si la déclaration a été faite au niveau globale.
La déclaration suivante :
se lit de l'intérieur vers l'extérieur, en spirale en commençant par le nom de la variable et en commençant à tourner par la droite (tout en mettant un doigt sur le nez et en prononçant très vite l'incantation kerniganetrichie).
La déclaration suivante est valide :
# voire aussi
Posté par Krunch (site web personnel) . Évalué à 2. Dernière modification le 15 août 2023 à 14:47.
https://web.archive.org/web/20131002073307/http://www.run.montefiore.ulg.ac.be:80/~martin/resources/kung-f00.html
https://web.archive.org/web/20230228041817/https://blog.joren.ga/less-known-c
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
# Facile
Posté par Misc (site web personnel) . Évalué à 9.
Vu qu'on a pas le reste du code, j'ai le droit de supposer que les variables sont inutilisés, donc d'optimiser ça en retirant le code mort, donc ça crée un binaire qui fait rien.
Je viens de vérifier codant un main avec cette ligne et un main avec rien. Quand je compile avec -s, il y a 4 lignes en plus:
Sauf erreur de ma part, ça initialise 2 variable à 0, et copie une variable de la stack vers ailleurs (un ailleurs mis à 0 plus tot).
Avec gcc -O3, ça donne bien la même chose entre les 2 codes (cad, rien), ergo, mon analyse est correct.
[^] # Re: Facile
Posté par serge_sans_paille (site web personnel) . Évalué à 3.
Bien tenté ;-)
En l'absence d'indication, on peut aussi imaginer que les déclarations soient globales, ce qui rend l'ensemble nettement plus intéressant (à défaut d'être complètement utile) et produit le code suivant, même en
-O3
(et à juste titre) (cf. https://godbolt.org/z/cYP6j1bsh)Finalement, la seule vraie difficulté du quizz est effectivement jetée aux oubliettes, bien joué !
# Bon
Posté par 2PetitsVerres . Évalué à 2.
Je commencerais par dire :
En tout cas je supprime cette ligne, et je regarde si ça compile encore, auquel cas c'est bien, sinon tant pis, je change des trucs au hasard jusqu'à ce que ça compile, et donc une fois que c'est compilé, c'est que c'est correct.
Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.