OVH Cloud OVH Cloud

Vider le buffer associe a stdin

98 réponses
Avatar
korchkidu
Bonjour,

je me pose une question par rapport a la maniere classique de vider le
buffer associe a stdin:

c = getchar();
if (c != ’\n’)
while ( (getchar()) != ’\n’) {
};

Que se passe t-il si stdin ne contient aucun \n? (fichier contenant une
ligne mais aucun \n par exemple). Dans ce cas, il me semble que l'on
pourrait avoir un probleme non?

Comment feriez vous pour resoudre ce probleme? (J'ai bien une petite
idee mais je prefere savoir si c'est la bonne..;) )

Merci d'avance pour vos reponses,
K.

8 réponses

6 7 8 9 10
Avatar
drkm
James Kanze writes:

drkm writes:

|> [ X-Post f.c.l.c et f.c.l.c++, Fu2 f.c.l.c++. ]

|> Gabriel Dos Reis writes:

|> > drkm writes:

|> > | James Kanze writes:

|> > | > Il n'y a pas, formellement, une interdiction de surcharge.

|> > | 7.4/6 :

|> > | At most one function with a particular name can have C
|> > | language linkage.

|> > oui, mais tu peux surcharger sur le linkage. Sic.

|> Je la connaissais pas, celle-là. Comment se passe la résolution de
|> surcharge ?

En fait, je pensais plutôt au fait que tu peux surcharger une fonction
extern "C" avec d'autres fonctions extern "C".


Ce qui n'est pas permis, si ?

Mais le surcharge sur le
linkage marche aussi, comme n'importe quel autre surcharge. (Comme j'ai
dit dans le thread, extern "C" joue sur les types.) Même, il y en a des
cas dans la norme, comme atexit.


Tiens, dans ce cas, la norme donne les déclarations (18.3/3) :

extern "C" int atexit( void ( * f )( void ) ) ;
extern "C++" int atexit( void ( * f )( void ) ) ;

Est-ce équivalent à :

typedef void ( * funcType )( void ) ;
extern "C" int atexit( funcType ) ;
extern "C++" int atexit( funcType ) ;

ou à (ce que je pense) :

typedef void ( * funcType )( void ) ;
int atexit( funcType ) ;
extern "C" {
typedef void ( * cFuncType )( void ) ;
int atexit( cFuncType ) ;
}

Mais pour le petit exemple :

typedef void (*pfCpp)( void * ) ;
extern void f( void* ) ;
extern "C" {
typedef void (*pfC)( void * ) ;
extern void g( void* ) ;
}

void h( pfCpp ) ; // #1
void h( pfC ) ; // #2

h( f ) ; // appelle #1
h( g ) ; // appelle #2

Exactement comme n'importe quel autre surcharge, en fait.


Car le linkage fait partie du système de types. Ce qui me fait dire
que je me suis sans doute un peu mépris lorsque Gaby a dit que l'on
pouvait « surcharger sur le linkage ». J'ai cru qu'il parlait par
exemple de :

extern "C" void f() ;
extern "C++" void f() ;

ce qui m'amenait à la question « comment se passe la résolution de
surcharge dans ce cas ».

Mais si cela n'est pas permis, ok, il s'agit juste de ce que le
linkage fait partie du système de types, et que l'on peut donc jouer
avec dans les types des arguments, dans les surcharges. Et non que le
linkage de la fonction elle-même en permet une surcharge.

Quelle est donc la situation, à cet égard ?

Au fait, n'est-ce pas un peu bizarre de faire intervenir le linkage
dans le système de types ? Quels sont les arguments, pour ou contre ?

--drkm

Avatar
James Kanze
drkm writes:

|> James Kanze writes:

|> > drkm writes:

|> > |> Gabriel Dos Reis writes:

|> > |> > drkm writes:

|> > |> > | James Kanze writes:

|> > |> > | > Il n'y a pas, formellement, une interdiction de surcharge.

|> > |> > | 7.4/6 :

|> > |> > | At most one function with a particular name can have
|> > |> > | C language linkage.

|> > |> > oui, mais tu peux surcharger sur le linkage. Sic.

|> > |> Je la connaissais pas, celle-là. Comment se passe la
|> > |> résolution de surcharge ?

|> > En fait, je pensais plutôt au fait que tu peux surcharger une fonction
|> > extern "C" avec d'autres fonctions extern "C".

|> Ce qui n'est pas permis, si ?

C'était évidemment une fautte de frappe. Ce que je voulais dire, c'est
que tu peux surcharger une fonction extern "C" avec d'autres fonctions
extern "C++". C'est ce que je voulais dire par « il n'y a pas
d'interdiction de surcharge » : quelque chose comme :

extern "C" void f( int ) ;
void f( double ) ;

est tout à fait légal, et la fonction extern "C" est bien surchargée.

|> > Mais le surcharge
|> > sur le linkage marche aussi, comme n'importe quel autre surcharge.
|> > (Comme j'ai dit dans le thread, extern "C" joue sur les types.)
|> > Même, il y en a des cas dans la norme, comme atexit.

|> Tiens, dans ce cas, la norme donne les déclarations (18.3/3) :

|> extern "C" int atexit( void ( * f )( void ) ) ;
|> extern "C++" int atexit( void ( * f )( void ) ) ;

|> Est-ce équivalent à :

|> typedef void ( * funcType )( void ) ;
|> extern "C" int atexit( funcType ) ;
|> extern "C++" int atexit( funcType ) ;

|> ou à (ce que je pense) :

|> typedef void ( * funcType )( void ) ;
|> int atexit( funcType ) ;
|> extern "C" {
|> typedef void ( * cFuncType )( void ) ;
|> int atexit( cFuncType ) ;
|> }

Le deuxième. En revanche, ou je ne suis pas sûr (Gaby ?) :

extern "C" void
f()
{
void (*p)() ;
}

Je crois que p a un type extern "C" aussi, mais je ne suis pas 100% sûr.

|> > Mais pour le petit exemple :

|> > typedef void (*pfCpp)( void * ) ;
|> > extern void f( void* ) ;
|> > extern "C" {
|> > typedef void (*pfC)( void * ) ;
|> > extern void g( void* ) ;
|> > }

|> > void h( pfCpp ) ; // #1
|> > void h( pfC ) ; // #2

|> > h( f ) ; // appelle #1
|> > h( g ) ; // appelle #2

|> > Exactement comme n'importe quel autre surcharge, en fait.

|> Car le linkage fait partie du système de types. Ce qui me fait
|> dire que je me suis sans doute un peu mépris lorsque Gaby a dit que
|> l'on pouvait « surcharger sur le linkage ». J'ai cru qu'il parlait
|> par exemple de :

|> extern "C" void f() ;
|> extern "C++" void f() ;

|> ce qui m'amenait à la question « comment se passe la résolution de
|> surcharge dans ce cas ».

|> Mais si cela n'est pas permis, ok, il s'agit juste de ce que le
|> linkage fait partie du système de types, et que l'on peut donc jouer
|> avec dans les types des arguments, dans les surcharges. Et non que
|> le linkage de la fonction elle-même en permet une surcharge.

Je ne crois pas que c'est permis. En tout cas, l'appel serait ambigu,
parce que la résolution du surcharge ne se fait qu'à partir des
paramètres. À une exception près :

extern "C" { typedef void (*pfC)() ; }
extern "C++" { typedef void (*pfCpp)() ; }

pfC p1 = f ; // prend la fonction « extern "C" ».
pfCpp p2 = f ; // prend la fonction « extern "C++" ».

|> Quelle est donc la situation, à cet égard ?

Je crois que c'est illégal, mais je suis loin d'en être sûr.

|> Au fait, n'est-ce pas un peu bizarre de faire intervenir le
|> linkage dans le système de types ? Quels sont les arguments, pour ou
|> contre ?

L'argument pour est clair -- on évite une certaine classe d'erreurs. Si
j'ai une fonction qui s'attend à un pointeur vers une fonction C, et par
erreur je lui passe l'adresse d'une fonction C++, c'est une erreur de
compilation, et non un comportement indéfini.

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

| [ X-Post f.c.l.c et f.c.l.c++, Fu2 f.c.l.c++. ]
|
| Gabriel Dos Reis writes:
|
| > drkm writes:
|
| > | James Kanze writes:
|
| > | > Il n'y a pas, formellement, une interdiction de surcharge.
|
| > | 7.4/6 :
|
| > | At most one function with a particular name can have C language
| > | linkage.
|
| > oui, mais tu peux surcharger sur le linkage. Sic.
|
| Je la connaissais pas, celle-là. Comment se passe la résolution de
| surcharge ?

Comme dans les autres cas.

-- Gaby
Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis writes:
|
| |> drkm writes:
|
| |> | James Kanze writes:
|
| |> | > l'appel de g(), dans h(), se ferait selon les règles C, tandis
| |> | > que l'appel de f() (dans g()) se ferait selon les règles C++,
| |> | > même s'il se trouve dans un bloc extern "C".
|
| |> | Oui. Mais c'est tout de même bien au niveau de la génération de
| |> | code que se manifestent les conventions d'appel C, non ? En fait,
| |> | je pensais principalement à la décoration des noms et au passage
| |> | des paramètres, ce qui pour moi a trait à la génération de code.
|
| |> | Ai-je loupé quelque chose ?
|
| |> Tu peux aussi surcharger selon le linkage :
|
| |> extern "C" double abs(double); // #1
| |> double abs(double); // #2, surcharge de #1
|
| Et comment est-ce qu'on résoud le surcharge, quand j'appelle abs( 3.14 ) ?

Ambigü, comme d'hab.


extern "C" typdef double (c_fun)(double);
extern "C++" typedef double (cxx_fun)(double);
c_fun abs; // #1
cxx_fun abs; // #2

double apply(c_fun* f, double x) { return f(x); }

int main() { apply(abs, 2.14); } // select #1

-- Gaby
Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| [ X-Post f.c.l.c et f.c.l.c++, Fu2 f.c.l.c++. ]

| Gabriel Dos Reis writes:

| > oui, mais tu peux surcharger sur le linkage. Sic.

| Je la connaissais pas, celle-là. Comment se passe la résolution de
| surcharge ?

Comme dans les autres cas.


C'est à dire que le linkage fait partie du système de type, et que
la résolution est faire sur les argument de la fonction ?

--drkm

Avatar
Gabriel Dos Reis
drkm writes:

| Gabriel Dos Reis writes:
|
| > drkm writes:
|
| > | [ X-Post f.c.l.c et f.c.l.c++, Fu2 f.c.l.c++. ]
|
| > | Gabriel Dos Reis writes:
|
| > | > oui, mais tu peux surcharger sur le linkage. Sic.
|
| > | Je la connaissais pas, celle-là. Comment se passe la résolution de
| > | surcharge ?
|
| > Comme dans les autres cas.
|
| C'est à dire que le linkage fait partie du système de type, et que
| la résolution est faire sur les argument de la fonction ?

Oui -- et dans le cas où on prend implicitement l'adresse de la
fonction, le type de destination joue pour sélectionner la bonne
fonction.

-- Gaby
Avatar
kanze
Gabriel Dos Reis wrote in message
news:...
drkm writes:

| Gabriel Dos Reis writes:

| > drkm writes:

| > | Gabriel Dos Reis writes:

| > | > oui, mais tu peux surcharger sur le linkage. Sic.

| > | Je la connaissais pas, celle-là. Comment se passe la
| > | résolution de surcharge ?

| > Comme dans les autres cas.

| C'est à dire que le linkage fait partie du système de type, et que
| la résolution est faire sur les argument de la fonction ?

Oui -- et dans le cas où on prend implicitement l'adresse de la
fonction, le type de destination joue pour sélectionner la bonne
fonction.


Aussi quand on en prend l'adresse explicitement, non ?

--
James Kanze GABI Software http://www.gabi-soft.fr
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
Gabriel Dos Reis
writes:

| Gabriel Dos Reis wrote in message
| news:...
| > drkm writes:
|
| > | Gabriel Dos Reis writes:
|
| > | > drkm writes:
|
| > | > | Gabriel Dos Reis writes:
|
| > | > | > oui, mais tu peux surcharger sur le linkage. Sic.
|
| > | > | Je la connaissais pas, celle-là. Comment se passe la
| > | > | résolution de surcharge ?
|
| > | > Comme dans les autres cas.
|
| > | C'est à dire que le linkage fait partie du système de type, et que
| > | la résolution est faire sur les argument de la fonction ?
|
| > Oui -- et dans le cas où on prend implicitement l'adresse de la
| > fonction, le type de destination joue pour sélectionner la bonne
| > fonction.
|
| Aussi quand on en prend l'adresse explicitement, non ?

Exact.

(J'avais une façon particulière de prendre l'adresse en tête ; ce qui
a donné lieu à cette formulation).

-- Gaby
6 7 8 9 10