On Sun, 9 Nov 2003 14:34:28 +0000 (UTC),
(Marc Espie) wrote:J'avoue que je ne vois pas trop l'interet d'utiliser un langage si, dans
le meme temps, on nie certaines des constructions idiomatiques les plus
repandues du-dit langage...
Mais break est-il une "expression idiomatique" ou une "sale bidouille
à la 'goto'" ? That is the question...
On Sun, 9 Nov 2003 14:34:28 +0000 (UTC), espie@tetto.gentiane.org
(Marc Espie) wrote:
J'avoue que je ne vois pas trop l'interet d'utiliser un langage si, dans
le meme temps, on nie certaines des constructions idiomatiques les plus
repandues du-dit langage...
Mais break est-il une "expression idiomatique" ou une "sale bidouille
à la 'goto'" ? That is the question...
On Sun, 9 Nov 2003 14:34:28 +0000 (UTC),
(Marc Espie) wrote:J'avoue que je ne vois pas trop l'interet d'utiliser un langage si, dans
le meme temps, on nie certaines des constructions idiomatiques les plus
repandues du-dit langage...
Mais break est-il une "expression idiomatique" ou une "sale bidouille
à la 'goto'" ? That is the question...
Tu reconnias probablement le bout code de code suivant
/* Decode the list of parameter types for a function type.
Given the list of things declared inside the parens,
return a list of types.
We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
flag. If unset, we append void_list_node. A parmlist declared
as `(void)' is accepted as the empty parmlist.
Also set last_function_parms to the chain of PARM_DECLs. */
static tree
grokparms (tree first_parm)
{
tree result = NULL_TREE;
tree decls = NULL_TREE;
int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
tree parm, chain;
int any_error = 0;
my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
for (parm = first_parm; parm != NULL_TREE; parm = chain)
{
tree type = NULL_TREE;
tree decl = TREE_VALUE (parm);
tree init = TREE_PURPOSE (parm);
tree specs, attrs;
chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */
if (TREE_CODE (decl) != VOID_TYPE
&& TREE_CODE (decl) != TREE_LIST)
{
/* Give various messages as the need arises. */
if (TREE_CODE (decl) == STRING_CST)
error ("invalid string constant `%E'", decl);
else if (TREE_CODE (decl) == INTEGER_CST)
error ("invalid integer constant in parameter list, did
you forget to give parameter name?");
continue;
}
if (parm == void_list_node)
break;
split_specs_attrs (TREE_PURPOSE (decl), &specs, &attrs);
decl = grokdeclarator (TREE_VALUE (decl), specs,
PARM, init != NULL_TREE, &attrs);
if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
if (attrs)
cplus_decl_attributes (&decl, attrs, 0);
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
if (same_type_p (type, void_type_node)
&& !DECL_NAME (decl) && !result && !chain && !ellipsis)
/* this is a parmlist of `(void)', which is ok. */
break;
cxx_incomplete_type_error (decl, type);
/* It's not a good idea to actually create parameters of
type `void'; other parts of the compiler assume that a
void type terminates the parameter list. */
type = error_mark_node;
TREE_TYPE (decl) = error_mark_node;
}
if (type != error_mark_node)
{
/* Top-level qualifiers on the parameters are
ignored for function types. */
type = cp_build_qualified_type (type, 0);
if (TREE_CODE (type) == METHOD_TYPE)
{
error ("parameter `%D' invalidly declared method type", decl);
type = build_pointer_type (type);
TREE_TYPE (decl) = type;
}
else if (abstract_virtuals_error (decl, type))
any_error = 1; /* Seems like a good idea. */
else if (POINTER_TYPE_P (type))
{
/* [dcl.fct]/6, parameter types cannot contain pointers
(references) to arrays of unknown bound. */
tree t = TREE_TYPE (type);
int ptr = TYPE_PTR_P (type);
while (1)
{
if (TYPE_PTR_P (t))
ptr = 1;
else if (TREE_CODE (t) != ARRAY_TYPE)
break;
else if (!TYPE_DOMAIN (t))
break;
t = TREE_TYPE (t);
}
if (TREE_CODE (t) == ARRAY_TYPE)
error ("parameter `%D' includes %s to array of unknown
bound `%T'",
decl, ptr ? "pointer" : "reference", t);
}
if (!any_error && init)
init = check_default_argument (decl, init);
else
init = NULL_TREE;
}
TREE_CHAIN (decl) = decls;
decls = decl;
result = tree_cons (init, type, result);
}
decls = nreverse (decls);
result = nreverse (result);
if (!ellipsis)
result = chainon (result, void_list_node);
last_function_parms = decls;
return result;
}
-- Gaby
Tu reconnias probablement le bout code de code suivant
/* Decode the list of parameter types for a function type.
Given the list of things declared inside the parens,
return a list of types.
We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
flag. If unset, we append void_list_node. A parmlist declared
as `(void)' is accepted as the empty parmlist.
Also set last_function_parms to the chain of PARM_DECLs. */
static tree
grokparms (tree first_parm)
{
tree result = NULL_TREE;
tree decls = NULL_TREE;
int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
tree parm, chain;
int any_error = 0;
my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
for (parm = first_parm; parm != NULL_TREE; parm = chain)
{
tree type = NULL_TREE;
tree decl = TREE_VALUE (parm);
tree init = TREE_PURPOSE (parm);
tree specs, attrs;
chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */
if (TREE_CODE (decl) != VOID_TYPE
&& TREE_CODE (decl) != TREE_LIST)
{
/* Give various messages as the need arises. */
if (TREE_CODE (decl) == STRING_CST)
error ("invalid string constant `%E'", decl);
else if (TREE_CODE (decl) == INTEGER_CST)
error ("invalid integer constant in parameter list, did
you forget to give parameter name?");
continue;
}
if (parm == void_list_node)
break;
split_specs_attrs (TREE_PURPOSE (decl), &specs, &attrs);
decl = grokdeclarator (TREE_VALUE (decl), specs,
PARM, init != NULL_TREE, &attrs);
if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
if (attrs)
cplus_decl_attributes (&decl, attrs, 0);
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
if (same_type_p (type, void_type_node)
&& !DECL_NAME (decl) && !result && !chain && !ellipsis)
/* this is a parmlist of `(void)', which is ok. */
break;
cxx_incomplete_type_error (decl, type);
/* It's not a good idea to actually create parameters of
type `void'; other parts of the compiler assume that a
void type terminates the parameter list. */
type = error_mark_node;
TREE_TYPE (decl) = error_mark_node;
}
if (type != error_mark_node)
{
/* Top-level qualifiers on the parameters are
ignored for function types. */
type = cp_build_qualified_type (type, 0);
if (TREE_CODE (type) == METHOD_TYPE)
{
error ("parameter `%D' invalidly declared method type", decl);
type = build_pointer_type (type);
TREE_TYPE (decl) = type;
}
else if (abstract_virtuals_error (decl, type))
any_error = 1; /* Seems like a good idea. */
else if (POINTER_TYPE_P (type))
{
/* [dcl.fct]/6, parameter types cannot contain pointers
(references) to arrays of unknown bound. */
tree t = TREE_TYPE (type);
int ptr = TYPE_PTR_P (type);
while (1)
{
if (TYPE_PTR_P (t))
ptr = 1;
else if (TREE_CODE (t) != ARRAY_TYPE)
break;
else if (!TYPE_DOMAIN (t))
break;
t = TREE_TYPE (t);
}
if (TREE_CODE (t) == ARRAY_TYPE)
error ("parameter `%D' includes %s to array of unknown
bound `%T'",
decl, ptr ? "pointer" : "reference", t);
}
if (!any_error && init)
init = check_default_argument (decl, init);
else
init = NULL_TREE;
}
TREE_CHAIN (decl) = decls;
decls = decl;
result = tree_cons (init, type, result);
}
decls = nreverse (decls);
result = nreverse (result);
if (!ellipsis)
result = chainon (result, void_list_node);
last_function_parms = decls;
return result;
}
-- Gaby
Tu reconnias probablement le bout code de code suivant
/* Decode the list of parameter types for a function type.
Given the list of things declared inside the parens,
return a list of types.
We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
flag. If unset, we append void_list_node. A parmlist declared
as `(void)' is accepted as the empty parmlist.
Also set last_function_parms to the chain of PARM_DECLs. */
static tree
grokparms (tree first_parm)
{
tree result = NULL_TREE;
tree decls = NULL_TREE;
int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
tree parm, chain;
int any_error = 0;
my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
for (parm = first_parm; parm != NULL_TREE; parm = chain)
{
tree type = NULL_TREE;
tree decl = TREE_VALUE (parm);
tree init = TREE_PURPOSE (parm);
tree specs, attrs;
chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */
if (TREE_CODE (decl) != VOID_TYPE
&& TREE_CODE (decl) != TREE_LIST)
{
/* Give various messages as the need arises. */
if (TREE_CODE (decl) == STRING_CST)
error ("invalid string constant `%E'", decl);
else if (TREE_CODE (decl) == INTEGER_CST)
error ("invalid integer constant in parameter list, did
you forget to give parameter name?");
continue;
}
if (parm == void_list_node)
break;
split_specs_attrs (TREE_PURPOSE (decl), &specs, &attrs);
decl = grokdeclarator (TREE_VALUE (decl), specs,
PARM, init != NULL_TREE, &attrs);
if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
if (attrs)
cplus_decl_attributes (&decl, attrs, 0);
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
if (same_type_p (type, void_type_node)
&& !DECL_NAME (decl) && !result && !chain && !ellipsis)
/* this is a parmlist of `(void)', which is ok. */
break;
cxx_incomplete_type_error (decl, type);
/* It's not a good idea to actually create parameters of
type `void'; other parts of the compiler assume that a
void type terminates the parameter list. */
type = error_mark_node;
TREE_TYPE (decl) = error_mark_node;
}
if (type != error_mark_node)
{
/* Top-level qualifiers on the parameters are
ignored for function types. */
type = cp_build_qualified_type (type, 0);
if (TREE_CODE (type) == METHOD_TYPE)
{
error ("parameter `%D' invalidly declared method type", decl);
type = build_pointer_type (type);
TREE_TYPE (decl) = type;
}
else if (abstract_virtuals_error (decl, type))
any_error = 1; /* Seems like a good idea. */
else if (POINTER_TYPE_P (type))
{
/* [dcl.fct]/6, parameter types cannot contain pointers
(references) to arrays of unknown bound. */
tree t = TREE_TYPE (type);
int ptr = TYPE_PTR_P (type);
while (1)
{
if (TYPE_PTR_P (t))
ptr = 1;
else if (TREE_CODE (t) != ARRAY_TYPE)
break;
else if (!TYPE_DOMAIN (t))
break;
t = TREE_TYPE (t);
}
if (TREE_CODE (t) == ARRAY_TYPE)
error ("parameter `%D' includes %s to array of unknown
bound `%T'",
decl, ptr ? "pointer" : "reference", t);
}
if (!any_error && init)
init = check_default_argument (decl, init);
else
init = NULL_TREE;
}
TREE_CHAIN (decl) = decls;
decls = decl;
result = tree_cons (init, type, result);
}
decls = nreverse (decls);
result = nreverse (result);
if (!ellipsis)
result = chainon (result, void_list_node);
last_function_parms = decls;
return result;
}
-- Gaby
Ne penses tu pas qu une imbrication de if then else peut rendre un
algorithme
L appel d une fonction a un cout, non ?
Je suis pret a te soumettre une methode dirigee par une profonde
imbrication
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le continue
sont juste la facon `naturelle' de continuer. Par exemple, lorsque je
En effet. Mais il faut tout de même faire attention. On ne va pas non plus
se mettre à utiliser goto à tour de bras parce qu'il fait partie du
Mais break est-il une "expression idiomatique" ou une "sale bidouille
à la 'goto'" ? That is the question...
La reponse est claire: break ne pose aucun des problemes poses par goto.
Le gros probleme de goto, c'est un saut non local de n'importe ou a
Cote semantique, entre exprimer des conditions tordues a coup de variables
locales booleennes (toujours vachement evident a formaliser dans un
Ne penses tu pas qu une imbrication de if then else peut rendre un
algorithme
L appel d une fonction a un cout, non ?
Je suis pret a te soumettre une methode dirigee par une profonde
imbrication
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le continue
sont juste la facon `naturelle' de continuer. Par exemple, lorsque je
En effet. Mais il faut tout de même faire attention. On ne va pas non plus
se mettre à utiliser goto à tour de bras parce qu'il fait partie du
Mais break est-il une "expression idiomatique" ou une "sale bidouille
à la 'goto'" ? That is the question...
La reponse est claire: break ne pose aucun des problemes poses par goto.
Le gros probleme de goto, c'est un saut non local de n'importe ou a
Cote semantique, entre exprimer des conditions tordues a coup de variables
locales booleennes (toujours vachement evident a formaliser dans un
Ne penses tu pas qu une imbrication de if then else peut rendre un
algorithme
L appel d une fonction a un cout, non ?
Je suis pret a te soumettre une methode dirigee par une profonde
imbrication
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le continue
sont juste la facon `naturelle' de continuer. Par exemple, lorsque je
En effet. Mais il faut tout de même faire attention. On ne va pas non plus
se mettre à utiliser goto à tour de bras parce qu'il fait partie du
Mais break est-il une "expression idiomatique" ou une "sale bidouille
à la 'goto'" ? That is the question...
La reponse est claire: break ne pose aucun des problemes poses par goto.
Le gros probleme de goto, c'est un saut non local de n'importe ou a
Cote semantique, entre exprimer des conditions tordues a coup de variables
locales booleennes (toujours vachement evident a formaliser dans un
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le
continue sont juste la facon `naturelle' de continuer. Par exemple,
lorsque je suis en train de traiter un fichier de configuration
`oriente ligne', zapper les lignes de commentaires avec un `continue'
marche tres bien.
Il y a aussi toutes ces boucles ou la condition d'arret s'exprime au
milieu de la boucle qui donnent naturellement des
while (1) {
debut_de_boucle();
if (cond)
break;
fin_de_boucle();
}
Lorsque je n'ai pas de STL sous la main, une bonne boucle de recherche
dans un tableau ressemble souvent a:
for (i = 0; i < n; i++) {
if (element_trouve)
break;
}
pour moi...
(et, dans des cas plus compliques, c'est souvent plus immediat de
faire le boulot directement que d'aller pondre l'adaptateur qui va
bien pour utiliser un algo standard... et si c'est du code qui ne sera
pas etendu plus tard, ca ne sert a rien de vouloir faire general a
outrance)
c'est infiniment plus clair de separer proprement le parcours du
tableau de la recherche de l'element. Je trouve particulierement
atroce la variante pascalienne
for (i = 0; i < n && !found; i++) {
if (element_trouve)
found = true;
}
Le `found', dans ce contexte, n'ajoute pour moi que du bruit, et n'est
clairement pas idiomatique, ni du C, ni du C++.
En terme de robustesse du code, il n'apporte rien non plus. Aucune des
deux variantes n'est plus difficile a prouver que l'autre.
J'avoue que je ne vois pas trop l'interet d'utiliser un langage si,
dans le meme temps, on nie certaines des constructions idiomatiques
les plus repandues du-dit langage...
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le
continue sont juste la facon `naturelle' de continuer. Par exemple,
lorsque je suis en train de traiter un fichier de configuration
`oriente ligne', zapper les lignes de commentaires avec un `continue'
marche tres bien.
Il y a aussi toutes ces boucles ou la condition d'arret s'exprime au
milieu de la boucle qui donnent naturellement des
while (1) {
debut_de_boucle();
if (cond)
break;
fin_de_boucle();
}
Lorsque je n'ai pas de STL sous la main, une bonne boucle de recherche
dans un tableau ressemble souvent a:
for (i = 0; i < n; i++) {
if (element_trouve)
break;
}
pour moi...
(et, dans des cas plus compliques, c'est souvent plus immediat de
faire le boulot directement que d'aller pondre l'adaptateur qui va
bien pour utiliser un algo standard... et si c'est du code qui ne sera
pas etendu plus tard, ca ne sert a rien de vouloir faire general a
outrance)
c'est infiniment plus clair de separer proprement le parcours du
tableau de la recherche de l'element. Je trouve particulierement
atroce la variante pascalienne
for (i = 0; i < n && !found; i++) {
if (element_trouve)
found = true;
}
Le `found', dans ce contexte, n'ajoute pour moi que du bruit, et n'est
clairement pas idiomatique, ni du C, ni du C++.
En terme de robustesse du code, il n'apporte rien non plus. Aucune des
deux variantes n'est plus difficile a prouver que l'autre.
J'avoue que je ne vois pas trop l'interet d'utiliser un langage si,
dans le meme temps, on nie certaines des constructions idiomatiques
les plus repandues du-dit langage...
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le
continue sont juste la facon `naturelle' de continuer. Par exemple,
lorsque je suis en train de traiter un fichier de configuration
`oriente ligne', zapper les lignes de commentaires avec un `continue'
marche tres bien.
Il y a aussi toutes ces boucles ou la condition d'arret s'exprime au
milieu de la boucle qui donnent naturellement des
while (1) {
debut_de_boucle();
if (cond)
break;
fin_de_boucle();
}
Lorsque je n'ai pas de STL sous la main, une bonne boucle de recherche
dans un tableau ressemble souvent a:
for (i = 0; i < n; i++) {
if (element_trouve)
break;
}
pour moi...
(et, dans des cas plus compliques, c'est souvent plus immediat de
faire le boulot directement que d'aller pondre l'adaptateur qui va
bien pour utiliser un algo standard... et si c'est du code qui ne sera
pas etendu plus tard, ca ne sert a rien de vouloir faire general a
outrance)
c'est infiniment plus clair de separer proprement le parcours du
tableau de la recherche de l'element. Je trouve particulierement
atroce la variante pascalienne
for (i = 0; i < n && !found; i++) {
if (element_trouve)
found = true;
}
Le `found', dans ce contexte, n'ajoute pour moi que du bruit, et n'est
clairement pas idiomatique, ni du C, ni du C++.
En terme de robustesse du code, il n'apporte rien non plus. Aucune des
deux variantes n'est plus difficile a prouver que l'autre.
J'avoue que je ne vois pas trop l'interet d'utiliser un langage si,
dans le meme temps, on nie certaines des constructions idiomatiques
les plus repandues du-dit langage...
(Marc Espie) writes:
| J'avoue que je ne vois pas trop l'interet d'utiliser un langage si,
| dans le meme temps, on nie certaines des constructions idiomatiques
| les plus repandues du-dit langage...
et l'utilisation de « break » est si répandue que ça dans les codes de
qualité ?
espie@tetto.gentiane.org (Marc Espie) writes:
| J'avoue que je ne vois pas trop l'interet d'utiliser un langage si,
| dans le meme temps, on nie certaines des constructions idiomatiques
| les plus repandues du-dit langage...
et l'utilisation de « break » est si répandue que ça dans les codes de
qualité ?
(Marc Espie) writes:
| J'avoue que je ne vois pas trop l'interet d'utiliser un langage si,
| dans le meme temps, on nie certaines des constructions idiomatiques
| les plus repandues du-dit langage...
et l'utilisation de « break » est si répandue que ça dans les codes de
qualité ?
writes:
| Gabriel Dos Reis wrote in message
| news:...
| > (Marc Espie) writes:
| > | J'avoue que je ne vois pas trop l'interet d'utiliser un langage
| > | si, dans le meme temps, on nie certaines des constructions
| > | idiomatiques les plus repandues du-dit langage...
| > et l'utilisation de « break » est si répandue que ça dans les
| > codes de qualité ?
| Dans les switch, oui.
J'ai naturellement excepté les switch (comme l'indiquait le posteur
initial) -- même si je m'attend à moins de switch dans un programme
C++ que dans un programme C.
kanze@gabi-soft.fr writes:
| Gabriel Dos Reis <gdr@integrable-solutions.net> wrote in message
| news:<m3llqpmkb7.fsf@uniton.integrable-solutions.net>...
| > espie@tetto.gentiane.org (Marc Espie) writes:
| > | J'avoue que je ne vois pas trop l'interet d'utiliser un langage
| > | si, dans le meme temps, on nie certaines des constructions
| > | idiomatiques les plus repandues du-dit langage...
| > et l'utilisation de « break » est si répandue que ça dans les
| > codes de qualité ?
| Dans les switch, oui.
J'ai naturellement excepté les switch (comme l'indiquait le posteur
initial) -- même si je m'attend à moins de switch dans un programme
C++ que dans un programme C.
writes:
| Gabriel Dos Reis wrote in message
| news:...
| > (Marc Espie) writes:
| > | J'avoue que je ne vois pas trop l'interet d'utiliser un langage
| > | si, dans le meme temps, on nie certaines des constructions
| > | idiomatiques les plus repandues du-dit langage...
| > et l'utilisation de « break » est si répandue que ça dans les
| > codes de qualité ?
| Dans les switch, oui.
J'ai naturellement excepté les switch (comme l'indiquait le posteur
initial) -- même si je m'attend à moins de switch dans un programme
C++ que dans un programme C.
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le continue
sont juste la facon `naturelle' de continuer. Par exemple, lorsque je
suis en train de traiter un fichier de configuration `oriente ligne',
zapper les lignes de commentaires avec un `continue' marche tres bien.
Il y a aussi toutes ces boucles ou la condition d'arret s'exprime au
milieu de la boucle qui donnent naturellement des
while (1) {
debut_de_boucle();
if (cond)
break;
fin_de_boucle();
}
<snip>
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le continue
sont juste la facon `naturelle' de continuer. Par exemple, lorsque je
suis en train de traiter un fichier de configuration `oriente ligne',
zapper les lignes de commentaires avec un `continue' marche tres bien.
Il y a aussi toutes ces boucles ou la condition d'arret s'exprime au
milieu de la boucle qui donnent naturellement des
while (1) {
debut_de_boucle();
if (cond)
break;
fin_de_boucle();
}
<snip>
Bof, bof, bof... dans pas mal de cas, pour moi, le break et le continue
sont juste la facon `naturelle' de continuer. Par exemple, lorsque je
suis en train de traiter un fichier de configuration `oriente ligne',
zapper les lignes de commentaires avec un `continue' marche tres bien.
Il y a aussi toutes ces boucles ou la condition d'arret s'exprime au
milieu de la boucle qui donnent naturellement des
while (1) {
debut_de_boucle();
if (cond)
break;
fin_de_boucle();
}
<snip>