OVH Cloud OVH Cloud

size_t, bug dans VC++2005 ?

34 réponses
Avatar
Alain Gaillard
Bonjour à tous,

Je voudrais amener la discussion sur un post que j'ai lu dans
comp.lang.c++.moderated.
Quelqu'un pose une question à partir d'un éventuel bug de VC++ 2005 et
la discussion ne semble pas trancher catégoriquement.

Soit ce code:

int main()
{
size_t n = 8;

return n;
}

Notez bien l'absence de tout include.

VC++ 2005 compile ça sans broncher.

Pourtant selon 18.1 (draft 2005) il semble bien clair que size_t est
défini dans cstddef, lequel sur ce point est identique à stddef.h.

Il me semble bien que le standard C dit sans ambiguïté que stddef.h contient

typedef unsigned int size_t;

Encore plus étonnant, le stddef.h de VC++, inclus par cstddef ne
contient même pas le typedef (à moins que je n'ai la berlue)

AMHA le compilateur n'a pas à connaître size_t avant qu'on le lui ai
déclaré, et AMHA toujours c'est clairement un bug.

Qu'en pensez vous ?


--
Alain

10 réponses

1 2 3 4
Avatar
Fabien LE LEZ
On Fri, 18 Aug 2006 11:00:49 +0200, Alain Gaillard
:

Pourtant selon 18.1 (draft 2005) il semble bien clair que size_t est
défini dans cstddef, lequel sur ce point est identique à stddef.h.


Est-ce que le code

typedef double size_t;

renvoie une erreur ?

Avatar
Fabien LE LEZ
On Fri, 18 Aug 2006 11:00:49 +0200, Alain Gaillard
:

Il me semble bien que le standard C dit sans ambiguïté que stddef.h contient

typedef unsigned int size_t;


Et le standard C++, que dit-il ?


Je ne l'ai pas sous la main, mais le Stroustrup (6.2.6.2) me dit qu'un
prototype de new est :
void * operator new (size_t);

Étant donné que new est accessible sans avoir besoin d'inclure le
moindre en-tête, ne devrait-il pas en aller de même pour size_t ?

Même question pour std::exception, puisque new peut lancer une
exception.

Avatar
Alain Gaillard
On Fri, 18 Aug 2006 11:00:49 +0200, Alain Gaillard
:


Pourtant selon 18.1 (draft 2005) il semble bien clair que size_t est
défini dans cstddef, lequel sur ce point est identique à stddef.h.



Est-ce que le code

typedef double size_t;

renvoie une erreur ?




Bonne question. Je viens d'essayer

typedef unsigned int size_t;

int main()
{
size_t n = 8;

return n;
}

compile sans erreur

par contre si je mets

typedef unsigned long size_t;

alors je compilo a un hoquet:

"Error 1 error C2371: 'size_t' : redefinition; different basic types
c:sizetsizet.cpp 6
"

--
Alain


Avatar
Alain Gaillard

Et le standard C++, que dit-il ?


Je l'ai dt dans mon post initial...;

"selon 18.1 (draft 2005) il semble bien clair que size_t est défini dans
cstddef, lequel sur ce point est identique à stddef.h."
$

donc on doit trouver un typedef unsigned int size_t dans cstddef ou
stddef.h.

--
Alain

Avatar
Laurent Pointal
Bonjour à tous,

Je voudrais amener la discussion sur un post que j'ai lu dans
comp.lang.c++.moderated.
Quelqu'un pose une question à partir d'un éventuel bug de VC++ 2005 et
la discussion ne semble pas trancher catégoriquement.

Soit ce code:

int main()
{
size_t n = 8;

return n;
}

Notez bien l'absence de tout include.

VC++ 2005 compile ça sans broncher.

Pourtant selon 18.1 (draft 2005) il semble bien clair que size_t est
défini dans cstddef, lequel sur ce point est identique à stddef.h.

Il me semble bien que le standard C dit sans ambiguïté que stddef.h
contient

typedef unsigned int size_t;

Encore plus étonnant, le stddef.h de VC++, inclus par cstddef ne
contient même pas le typedef (à moins que je n'ai la berlue)

AMHA le compilateur n'a pas à connaître size_t avant qu'on le lui ai
déclaré, et AMHA toujours c'est clairement un bug.

Qu'en pensez vous ?


Est-ce qu'il n'y aurais pas des include automatiques liés à
l'environnement VC++2005, au type de projet créé, à des headers
précompilés... ?

Avatar
Alain Gaillard

Est-ce qu'il n'y aurais pas des include automatiques liés à
l'environnement VC++2005, au type de projet créé, à des headers
précompilés... ?


Bonne question, mais non. Aucun entête même précompilé sauf erreur
grossière de ma part.

--
Alain

Avatar
James Kanze
Fabien LE LEZ wrote:
On Fri, 18 Aug 2006 11:00:49 +0200, Alain Gaillard
:

Il me semble bien que le standard C dit sans ambiguïté que
stddef.h contient typedef unsigned int size_t;



Ainsi que <stdlib.h> et <string.h> (et peut-être d'autres que
j'oublie).

Et le standard C++, que dit-il ?


Que c'est pareil à C, sauf qu'un en-tête C++ peut en inclure un
autre. Inclure <string>, par exemple, et c'est prèsque sûr que
tu auras size_t aussi.

Je ne l'ai pas sous la main, mais le Stroustrup (6.2.6.2) me
dit qu'un prototype de new est :
void * operator new (size_t);

Étant donné que new est accessible sans avoir besoin d'inclure le
moindre en-tête, ne devrait-il pas en aller de même pour size_t ?


D'abord, size_t est un typedef. Ce qui veut dire que « void*
operator new( size_t ) » n'est qu'une façon de le déclarer --
la seule façon portable, en l'occurance, mais selon le système,
« void* operator new( unsigned int ) » ou « void* operator
new( unsigned long ) » serait aussi légal. A priori, le
compilateur lui-même utilise une de ces définitions. Le
compilateur sait le type qui résulte d'un sizeof -- le
véritable type, et non le typedef qui le déclare. Il n'a aucun
problème à utiliser ce type dans sa déclaration implicite de la
fonction operator new. Ensuite, c'est le problème de
l'implémenteur de la bibliothèque de s'assurer que le typedef
dans <stddef.h> et les autres correspond à ce que fait le
compilateur, et non l'inverse.

Même question pour std::exception, puisque new peut lancer une
exception.


C'est un argument plus valid. En effet, le compilateur est
obligé à connaître quelques classes de la bibliothèque, sans que
le moindre en-tête soit inclu. std::type_info est de loin le
plus essentiel, mais il faut aussi qu'il sache au moins que la
fonction operator new peut lever une exception qui s'appelle
std::bad_alloc.

D'après ce que j'ai compris, il doit garder ces informations
secrète, et ne les utiliser que dans les cas bien définis, et
que c'est au charge de la bibliothèque de fournir des
définitions compatibles, et que le programmeur n'en a accès qu'à
travers les définitions dans les en-têtes. (Je dis compatible,
et non identique, parce que j'imagine que dans la plupart des
compilateurs, type_info ait plutôt l'air d'une structure POD,
qu'on initialise statiquement comme un POD. En fait, il l'en
faut, parce qu'une classe définie comme l'est std::type_info
dans la norme, c'est impossible d'en avoir une instance.)

En somme, la norme définit ce qu'il faut, et l'implémentation se
débrouille pour qu'on l'a. Mais l'implémentation ne peut pas
être écrit elle en C++ conforme et 100% portable.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
Alain Gaillard

Je pense avoir résolu la question.
En cherchant dans le standard (draft 2005). Au verset 3.7.3-2 je vois
qu'un programme qui fait référence à std::size_t sans avoir inclus
l'en-tête correspondant est mal formé. Comme a prioiri, selon 1.4-8, une
implémentation doit rejeter un programme mal formé, VC++ 2005 est buggé.


--
Alain
Avatar
Alain Gaillard


Ainsi que <stdlib.h> et <string.h> (et peut-être d'autres que
j'oublie).


Sans doute, mais du point de vue du standard C++, car c'est bien le
point de départ, seul cstddef et donc stddef.h sont pris ne compte pour
size_t.

Quoi qu'il en soit je pense avoir résolu la question. Voir mon autre post.


--
Alain

Avatar
Gabriel Dos Reis
Alain Gaillard writes:

|
| Je pense avoir résolu la question.
| En cherchant dans le standard (draft 2005). Au verset 3.7.3-2 je vois
| qu'un programme qui fait référence à std::size_t sans avoir inclus
| l'en-tête correspondant est mal formé. Comme a prioiri, selon 1.4-8,
| une implémentation doit rejeter un programme mal formé, VC++ 2005 est
| buggé.

La norme ne dit pas qu'il doit refuser de compiler le programme :
juste émettre un diagnostic. Maintenant, ce qui constitue un diagnostic
est laissé à l'appréciation de l'implémentation.

-- Gaby
1 2 3 4