Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

C11 : la normalisation est achevée
Après douze ans de travaux, multithreading et Unicode au menu

Le , par Gordon Fowler

0PARTAGES

11  0 
Voilà qui est fait. Après douze ans de travaux, la normalisation du C1.x vient d’être bouclée par l’International Organization for Standardization.

C11 succède donc à C99, réalisé en 1999, et propose la prise en charge du multithreading (autrement dit l’utilisation des différents cœurs d’un processeur pour accélérer les traitements et les processus) et de l’Unicode.


Dennis Ritchie, créateur du C

Pour rappel, le C est un langage de programmation impératif conçu en 1972 au sein des Bell Labs pour la programmation système. Inventé avec UNIX, C est devenu en quelques années un des langages les plus utilisés. De nombreux autres comme C++, C#, Objective-C mais aussi Java ou PHP en reprennent bien des aspects.

Son créateur, Dennis Ritchie, est décédé en novembre dernier, suscitant une très vive émotion et une reconnaissance unanime au sein du monde IT.

Cette certification lui aurait certainement fait plaisir.

Le nouveau standard ISO/IEC 9899:2011 est disponible depuis cette page

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de rt15
Membre éclairé https://www.developpez.com
Le 17/01/2012 à 11:57
Le but de restrict n'est pas du tout d'empêcher le développeur ou le compilateur de faire des bêtises.
Le but est de préciser au compilo qu'il n'y a pas d'overlap.
Cette information permet au compilo de générer un code plus rapide dans certains cas.
Et le compilo ne peut généralement pas deviner cette information que l'on utilise -O3 ou pas. Pour le déterminer, il faut qu'il vérifie dans le source que lors des appels (Ou de l'appel, si la fonction est inliné) qu'il ne peut pas y avoir d'overlap car les paramètres sont "différents". Jolie casse tête. Et dans certains cas, c'est même tout à fait impossible car il ne peut pas connaître tous les appels d'avance (Cas d'une fonction exportée par une librairie).

Considérons une fonction plus proche de ce qui peut exister, c'est à dire une fonction updatePoints qui prend en paramètre :
1/ Un tableau de points(Coordonnées x et y).
2/ Le nombre d'élément du tableau.
3/ Un pointeur vers un point delta.

Le but de la fonction est d'ajouter à tous les points du tableau le delta contenu dans le paramètre trois.
Code : Sélectionner tout
1
2
3
4
pour i de 0 à n - 1 
  points[i].x += delta.x; 
  points[i].y += delta.y; 
fait;
Ca revient à peu près à une bête translation d'un nuage de points dans un espace 2D. D'un point de vue fonctionnel, il n'y aura a jamais d'overlap entre "points" et "delta". Le programmeur le sait. Le compilo ne le sait pas forcément si le programmeur ne lui indique pas.

Code C : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h> 
  
#define POINT_COUNT 4 
  
typedef struct 
{ 
  int x; 
  int y; 
} 
MY_POINT; 
  
void updatePoints1(MY_POINT *lpPoints, int nPointCount, MY_POINT *lpDelta) 
{ 
  int i; 
  
  for (i = 0; i < nPointCount; i++) 
  { 
    lpPoints[i].x += lpDelta->x; 
    lpPoints[i].y += lpDelta->y; 
  } 
} 
  
void updatePoints2(MY_POINT *restrict lpPoints, int nPointCount, MY_POINT *restrict lpDelta) 
{ 
  int i; 
  
  for (i = 0; i < nPointCount; i++) 
  { 
    lpPoints[i].x += lpDelta->x; 
    lpPoints[i].y += lpDelta->y; 
  } 
} 
  
int main() 
{ 
  int i; 
  MY_POINT lpPoints[4]; 
  MY_POINT delta; 
  
  for (i = 0; i < POINT_COUNT; i++) 
  { 
    lpPoints[i].x = i; 
    lpPoints[i].y = 100 + i; 
  } 
  delta.x = 1; 
  delta.y = 1; 
  updatePoints1(lpPoints, POINT_COUNT, &delta); 
  updatePoints2(lpPoints, POINT_COUNT, &delta); 
  
  for (i = 0; i < POINT_COUNT; i++) 
  { 
    printf("%d %d\n", lpPoints[i].x, lpPoints[i].y); 
  } 
  
  return 0; 
}

La différence entre updatePoints1 et updatePoints2 est simplement l'ajout du mot clé restrict. La différence se fait dans le code généré. En effet, comme restrict indique que delta n'est pas modifié quand lpPoints est modifié, la valeur de delta n'a pas à être lue à chaque tour de boucle.

Code sans restrict :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
loop: 
mov     ecx,[esi]               # ecx = delta.x 
mov     eax,[esi+0x4]           # eax = delta.y 
add     [ebx+edx*8],ecx         # points[i].x += ecx 
add     [ebx+edx*8+0x4],eax     # points[i].y += eax 
inc     edx                     # i++ 
cmp     edx,0x4                 # si i < 4 alors ... 
jl      loop                    # ... saute à loop
Code avec restrict :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
mov     ecx,[esi] 
mov     eax,[esi+0x4] 
loop: 
add     [ebx+edx*8],ecx 
add     [ebx+edx*8+0x4],eax 
inc     edx 
cmp     edx,0x4 
jl      loop
Le corps de la boucle (Ce qui est exécuté 1000 fois s'il y a 1000 éléments) a 2 instructions de moins. D'autre part, toujours dans le cas de restrict, on peut inverser la boucle et ainsi remplacer inc/cmp/jl par dec/jnz et gagner une autre instruction. On ne peut pas faire cette inversion sans restrict car si delta peut être un élément de points, le résultat peut dépendre du sens de parcourt.

Bref, restrict, c'est une information qui en théorie peut bien aider le compilo à générer du code plus rapide. Il semble donc intéressant de l'avoir dans la norme.

[ ************** edit ************** ]
A noter que dans les faits, avec les flags de compilation :
gcc -O3 test.c -o test.exe -std=c99 -fstrict-aliasing
gcc 3.4.5 (Version ancienne... Il semble qu'il y ait eu des amélioration de restrict en 4.5) ne réalise pas l'optimisation permise par restrict ci-dessus.

Par contre, on peut forcer gcc 3.4.5 à réaliser l'optimisation en faisant une copie du contenu de lpDelta dans une variable locale. Le code C paraît alors moins optimisé, mais le code machine généré est comme celui ci-dessus "avec restrict".

Code c : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
void updatePoints1(MY_POINT *lpPoints, int nPointCount, MY_POINT *lpDelta) 
{ 
  int i; 
  MY_POINT delta; 
  
  delta = *lpDelta; 
  
  for (i = 0; i < nPointCount; i++) 
  { 
    lpPoints[i].x += delta.x; 
    lpPoints[i].y += delta.y; 
  } 
}

[ ************** edit 2 ************** ]
gcc 4.6.1 réalise correctement l'optimisation avec le mot clé restrict.
(Et il fait aussi l'optimisation en cas de copie locale de delta comme ci-dessus)
5  0 
Avatar de Bktero
Modérateur https://www.developpez.com
Le 18/01/2012 à 17:54
J'ai du mal à comprendre pourquoi certains ne "veulent" pas que ça soit un mot-clé du langage, car je ne vois pas comment le compilateur pourrait deviner le non chevauchement des entités... Si on souhaite avoir un tel mécanisme, il doit obligatoirement passer par un mot clé du langage, non ?

Après, j'entends parfaitement les arguments disant que ce n'est pas le rôle du langage de faire des optimisations mais au compilateur de se débrouiller. En même temps, il existe bien des directives #pragma pour influencer le compilateur (je ne m'en suis jamais servi perso ). On a aussi la possibilité de mettre un mot clé const à l'un des paramètres d'une fonction pour bloquer à la compilation quelque chose comme :

Code : Sélectionner tout
1
2
3
4
void maFonction(int const *a)
{
	(*a)++;
}


Ce genre de petits bonus dans le code me fait penser aux hints qu'on peut mettre dans le code SQL. Normalement, c'est le SGBD qui décide des plans d'exécutions mais il est parfois très utile de forcer un comportement quand on sait qu'il sera bénéfique.

Je trouve dommage de se priver d'"outils" pour faciliter la programmation ou améliorer la performance sous couvert d'une envie d'excellence, voire d'élitisme :
Citation Envoyé par souviron34
Ce qui, de mon point de vue, est une extrême mauvaise chose, ne povant qu'entraîner non seulement un usage abusif, non compatible, additionné d'un mélange des concepts, et surtout une fainéantise intellectuelle qui va à l'encotre de la philosophie du C..
Je suis d'accord qu'il faut savoir ce qu'on fait et être exigeant. Je ne suis pas sûr qu'ajouter un mot-clé comme restrict (et au contraire de const ?) amène à la fainéantise, bien au contraire : tu ne peux pas le mettre au hasard et te disant "au pire ça fera rien" (comme le disait TJean-Marc.Bourguet).
5  0 
Avatar de Médinoc
Expert éminent sénior https://www.developpez.com
Le 11/10/2018 à 21:12
Donc il n'y a plus qu'à attendre 2030 pour le voir dans Visual Studio?
4  0 
Avatar de Bktero
Modérateur https://www.developpez.com
Le 12/10/2018 à 8:49
Comment être indifférent à C18 ?

4  0 
Avatar de Davidbrcz
Rédacteur https://www.developpez.com
Le 29/12/2011 à 16:39
Y'a d'autres évolutions, dont un travail sur l'alignement, unions et structure anonymes ainsi que de rendre optionnel les VLA et les complex.

Le reste ICI
2  0 
Avatar de rt15
Membre éclairé https://www.developpez.com
Le 18/01/2012 à 20:41
Les développeurs C++ bavaient devant C++11. Ils trépignent en attendant que les compilos se mettent à jour.

Les développeurs C en sont encore à critiquer C99. Certains se demandent même si une quelconque évolution est nécessaire voire bénéfique.

Perso, je ne sais pas ce que j'aurai aimé voire dans C11.
2  0 
Avatar de souviron34
Expert éminent sénior https://www.developpez.com
Le 06/07/2012 à 15:02
Citation Envoyé par Bktero Voir le message

J'ai du mal à comprendre pourquoi les gens (car malheureusement, ce n'est pas que Microsoft) restent bloqués au C ANSI, qui a plus de 20 ans.
Pas compliqué :

Primo = compatibilité
Secondo = accessoire

Franchement, ce n'est en aucune manière de "grandes avancées", et ont plus été introduites pour faire le lien avec C++ et les notions utilisées que pour le C...

Si tu avais, comme les révisions de Fortran, quelque chose qui passe d'opérations "normales" aux mêmes sur des matrices (par exemple addition ou multiplication ou division) , là tu fais un bond en avant et ça vaut vraiment le coup. Si par contre tu "ajoutes" quelques "trucs" ici et là, franchement, entre le coût des modifs, de la maintenance, et les avantages, y'a en général pas photo (d'autant plus qu'un certain inombre de softs sont "certifiés", et repasser des certifications est payant - et cher).

Donc les "babioles" relativement peu évidentes à implanter et à assurer une compatibilité, et qui ne sont pas considérées comme de grosses différences de fond, ben....
2  0 
Avatar de gangsoleil
Modérateur https://www.developpez.com
Le 06/07/2012 à 15:23
VC++ implemente le C89, et le C++11.
Si tu veux du C autre que 89, ils disent que c'est probablement inclus dans C++11.
Si vraiment tu veux faire du C89, alors tu te tournes vers un compilateur C, car eux s'en foutent.

Le probleme qu'ils ne prennent pas en compte, c'est que C++ n'est pas un sur-ensemble du C !
La fonction suivante est par exemple valide en C (pre-89, 89, 99, et meme 11), mais incompilable en l'etat en C++ :

Code : Sélectionner tout
1
2
3
4
5
void fonction (int new)
{
   /* du code ici si on a envie, ou pas, on s'en fout */
   return;
}
Donc oui, lorsqu'on ecrit un programme dans un langage X, on utilise un compilateur pour le langage X, pas pour le langage Y, aussi proche soit-il.
2  0 
Avatar de grim7reaper
Membre éclairé https://www.developpez.com
Le 11/10/2018 à 19:20
Le C18 est sorti cette année, en juin, dans l’indifférence la plus absolue.

Bon en même temps, après 7 ans il y a 0 nouvelle fonctionnalités, seulement du bugfix et un bump de version pour __STDC_VERSION__.

Décevant…
2  0 
Avatar de grim7reaper
Membre éclairé https://www.developpez.com
Le 12/11/2018 à 16:21
Citation Envoyé par grim7reaper Voir le message
Le C18 est sorti cette année, en juin, dans l’indifférence la plus absolue.

Bon en même temps, après 7 ans il y a 0 nouvelle fonctionnalités, seulement du bugfix et un bump de version pour __STDC_VERSION__.

Décevant…
En revanche, le C2X semble beaucoup plus riche: https://gustedt.wordpress.com/2018/11/12/c2x/

On dirait qu'en plus d'ajouter de nouvelles fonctionnalités, y'a une passe de ménage (les déclarations K&R, le complément à un et le signe-magnitude ne seront plus supporté).
Y’aura peut-être du bignum aussi.

Ça aussi c’est peut-être intéressant, à voir (pas trop de détail pour le moment): "Add a new calling conventions with error return for library functions that avoids the use of errno"
2  0