/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Variadic til variadic
Fra : Soren Kuula


Dato : 17-06-04 19:28

Jeg vil implementere

void foo (const char *f, ...);

I nogle tilfælde skal der bare ske det samme som hvis foo blev erstattet
af printf.

Hvordan forwarder jeg lige hele ... til printf, uden noget med va_start
& va_end ?

MVH
Søren


 
 
Byrial Jensen (17-06-2004)
Kommentar
Fra : Byrial Jensen


Dato : 17-06-04 19:34

Soren Kuula wrote:
> Jeg vil implementere
>
> void foo (const char *f, ...);
>
> I nogle tilfælde skal der bare ske det samme som hvis foo blev erstattet
> af printf.
>
> Hvordan forwarder jeg lige hele ... til printf, uden noget med va_start
> & va_end ?

Det kan du ikke. Måden det gøres på, er:
- initialiser en va_list med va_start()
- kald vprintf() med din format-streng og din va_list.
- kald va_end()

Soren Kuula (17-06-2004)
Kommentar
Fra : Soren Kuula


Dato : 17-06-04 20:46

Hej, tak for svaret, men ...

> Det kan du ikke. Måden det gøres på, er:
> - initialiser en va_list med va_start()
> - kald vprintf() med din format-streng og din va_list.
> - kald va_end()


void dprintf(const char *format, ...) {
va_list ap;
va_start(ap, format);
printf(format, ap);
va_end(ap);
}


int main (int x) {
dprintf("%d hej \n", 10);
}

-->
[dongfang@granada]$ ./a.out
-1075492332 hej

Hvad er det jeg ikke har forstået

MVH
Søren


Bertel Brander (17-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 17-06-04 20:59

Soren Kuula wrote:
> Hej, tak for svaret, men ...
> void dprintf(const char *format, ...) {
> va_list ap;
> va_start(ap, format);
> printf(format, ap);

vprintf(format, ap);

> va_end(ap);
> }
>
>
> int main (int x) {
man skal bruge en af:

int main(void)
int main()
int main(int argc, char *argv[])
int main(int argc, char **argv)

/b

Soren Kuula (17-06-2004)
Kommentar
Fra : Soren Kuula


Dato : 17-06-04 21:36

Bertel Brander wrote:
> Soren Kuula wrote:
>
>> Hej, tak for svaret, men ...
>> void dprintf(const char *format, ...) {
>> va_list ap;
>> va_start(ap, format);
>> printf(format, ap);
>
>
> vprintf(format, ap);

Ææææææææh .. nå ja :)

Rødme.

Søren


Ukendt (17-06-2004)
Kommentar
Fra : Ukendt


Dato : 17-06-04 19:44

"Soren Kuula" <dongfang-remove_this@remove_this-bitplanet.net> wrote in
message news:6plAc.14615$Vf.817399@news000.worldonline.dk...
> Jeg vil implementere
> void foo (const char *f, ...);
> Hvordan forwarder jeg lige hele ... til printf, uden noget med va_start
> & va_end ?

Jeg mener at jeg for lang tid så noget source (ncurses), der gjorde netop
dette. Det stinker, men here goes....:

"foo.h" ----------------------
int foo(const char* f, ...);

"foo.c" ----------------------
/* don't include "foo.h" or <stdio.h>! */
int printf(double d1, double d2, double d3, double d4, double d5, double
d6);
int foo(double d1, double d2, double d3, double d4, double d5, double
d6)
{
return printf(d1,d2,d3,d4,d5,d6);
}

Som sagt det - det stinker. Der er naturligvis en grænse på antallet af
argumenter. På x86 arkitektur svarer 6 doubles til 12 pointers eller
integers, hvilket jo rækker et stykke. Der er sikkert også nogle
portabilitetsproblemer, men jeg kender for lidt til andre arkitekturer til
at kunne pege på dem.

mvh.
Martin



Igor V. Rafienko (17-06-2004)
Kommentar
Fra : Igor V. Rafienko


Dato : 17-06-04 20:37

[ Martin M. Pedersen ]

[ ... ]

> /* don't include "foo.h" or <stdio.h>! */


La oss for øyeblikket se bort i fra de praktiske problemene dette
medfører...


> int printf(double d1, double d2, double d3, double d4,
> double d5, double d6);
> int foo(double d1, double d2, double d3, double d4,
> double d5, double d6)
> {
> return printf(d1,d2,d3,d4,d5,d6);
> }
>
> Som sagt det - det stinker.


(Jeg er litt overrasket over at noen skulle ønske å sende en double
som første argument til printf, men det er kanskje en trykkfeil?)

Spørsmålet er, hva skjer dersom en kompilator har en spesifikk
prolog i variadic functions? (selv på x86)





ivr
--
<html><form><input type crash></form></html>

Ukendt (17-06-2004)
Kommentar
Fra : Ukendt


Dato : 17-06-04 21:13

"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvzn72563x.fsf@tyrfing.ifi.uio.no...
> (Jeg er litt overrasket over at noen skulle ønske å sende en double
> som første argument til printf, men det er kanskje en trykkfeil?)

Nej, det er ikke en trykfejl. Idéen er at sende parametrene videre uden at
lægge nogen fortolkning i dem. Hensigten med at bruge "double" er
naturligvis at den kan rumme alle de andre typer (eller kunne på de aktuelle
arkitekturer).

Det er cirka 10 år siden jeg kiggede på koden i ncurses, så jeg kan ikke
huske præcis hvordan den så ud. Men dette var tricket, og koden virker - hos
mig. ncurses er også vidt udbredt - jeg mener at den fortsat distribueres
med Linux.

Formålet må naturligvis have været at få det til at virke uden prototyper,
og at undgå buffer-problemet med sprintf().

> Spørsmålet er, hva skjer dersom en kompilator har en spesifikk
> prolog i variadic functions? (selv på x86)

Det går sikkert galt. Men der har ikke været behov for det før vi fik
prototyper, så hvorfor skulle der være et behov nu?

mvh.
Martin





Bertel Brander (17-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 17-06-04 21:29

Martin M. Pedersen wrote:

>
>
>>Spørsmålet er, hva skjer dersom en kompilator har en spesifikk
>>prolog i variadic functions? (selv på x86)
>
>
> Det går sikkert galt. Men der har ikke været behov for det før vi fik
> prototyper, så hvorfor skulle der være et behov nu?
>

Så vidt jeg ved har det altid (siden C89) været et krav at der var
prototyper for varadic funktioner.

Det er ikke ualmindeligt at parameterne bliver overført anderledes
for varadic funktioner end andre typer funktioner.

/b

Ukendt (17-06-2004)
Kommentar
Fra : Ukendt


Dato : 17-06-04 22:38

"Bertel Brander" <bertel@post4.tele.dk> wrote in message
news:40d1fe98$0$235$edfadb0f@dread16.news.tele.dk...
> > Det går sikkert galt. Men der har ikke været behov for det før vi fik
> > prototyper, så hvorfor skulle der være et behov nu?
> Så vidt jeg ved har det altid (siden C89) været et krav at der var
> prototyper for varadic funktioner.

I den C99 draft jeg har ved hånden er det defineret som undefined behaviour.
Måske ville det være bedre definere foo() som varadic - også i foo.c. En
bedre løsning er nok helt at lade være med at bruge teknikken

mvh.
Martin



Bertel Brander (17-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 17-06-04 21:49

Martin M. Pedersen wrote:

> "Soren Kuula" <dongfang-remove_this@remove_this-bitplanet.net> wrote in
> message news:6plAc.14615$Vf.817399@news000.worldonline.dk...
>
>>Jeg vil implementere
>> void foo (const char *f, ...);
>>Hvordan forwarder jeg lige hele ... til printf, uden noget med va_start
>>& va_end ?
>
>
> Jeg mener at jeg for lang tid så noget source (ncurses), der gjorde netop
> dette. Det stinker, men here goes....:
>
> "foo.h" ----------------------
> int foo(const char* f, ...);
>
> "foo.c" ----------------------
> /* don't include "foo.h" or <stdio.h>! */
> int printf(double d1, double d2, double d3, double d4, double d5, double
> d6);
> int foo(double d1, double d2, double d3, double d4, double d5, double
> d6)
> {
> return printf(d1,d2,d3,d4,d5,d6);
> }
>
> Som sagt det - det stinker. Der er naturligvis en grænse på antallet af
> argumenter. På x86 arkitektur svarer 6 doubles til 12 pointers eller
> integers, hvilket jo rækker et stykke. Der er sikkert også nogle
> portabilitetsproblemer, men jeg kender for lidt til andre arkitekturer til
> at kunne pege på dem.

Se:

http://www.gnu.org/prep/standards_28.html#SEC28

Bemærk at der står: "In practice, this works on all machines",
hvilket måske er en lille overdrivelse.

/b

Byrial Jensen (18-06-2004)
Kommentar
Fra : Byrial Jensen


Dato : 18-06-04 03:53

Bertel Brander wrote:
> Se:
>
> http://www.gnu.org/prep/standards_28.html#SEC28
>
> Bemærk at der står: "In practice, this works on all machines",
> hvilket måske er en lille overdrivelse.

Hmm! Der kan man blandt andet se følgende anbefalet:    

| printf ("size = %lu\n", (unsigned long) sizeof array);
| printf ("diff = %ld\n", (long) (pointer2 - pointer1));

Den korrekte måde at skrive ovennævnte 2 printf-sætninger på, er:

printf ("size = %zu\n", sizeof array);
printf ("diff = %td\n", pointer2 - pointer1);

Bertel Brander (18-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 18-06-04 20:01

Byrial Jensen wrote:
> Bertel Brander wrote:
>
>> Se:
>>
>> http://www.gnu.org/prep/standards_28.html#SEC28
>>
>> Bemærk at der står: "In practice, this works on all machines",
>> hvilket måske er en lille overdrivelse.
>
>
> Hmm! Der kan man blandt andet se følgende anbefalet:
>
> | printf ("size = %lu\n", (unsigned long) sizeof array);
> | printf ("diff = %ld\n", (long) (pointer2 - pointer1));
>
> Den korrekte måde at skrive ovennævnte 2 printf-sætninger på, er:
>
> printf ("size = %zu\n", sizeof array);
> printf ("diff = %td\n", pointer2 - pointer1);

%zu og %td er vist C99, og man kan måske ikke være sikker på at alle
bruger C99 kompilere.

Men at GNU kan få sig selv til at anbefale at bruge den anden
metode i år 2004 kan kun undre.

/b

Per Abrahamsen (21-06-2004)
Kommentar
Fra : Per Abrahamsen


Dato : 21-06-04 11:22

Bertel Brander <bertel@post4.tele.dk> writes:

> Martin M. Pedersen wrote:
>
>>
>>>Spørsmålet er, hva skjer dersom en kompilator har en spesifikk
>>>prolog i variadic functions? (selv på x86)
>> Det går sikkert galt. Men der har ikke været behov for det før vi fik
>> prototyper, så hvorfor skulle der være et behov nu?
>>
>
> Så vidt jeg ved har det altid (siden C89) været et krav at der var
> prototyper for varadic funktioner.

Curses er meget ældre end C89. Mange C ABI'er er også betydeligt
ældre end C89.


Per Abrahamsen (21-06-2004)
Kommentar
Fra : Per Abrahamsen


Dato : 21-06-04 11:29

Bertel Brander <bertel@post4.tele.dk> writes:

> %zu og %td er vist C99, og man kan måske ikke være sikker på at alle
> bruger C99 kompilere.

Det er vist stadig de færreste der gør det.

> Men at GNU kan få sig selv til at anbefale at bruge den anden
> metode i år 2004 kan kun undre.

Tjah, det var først i 2003 at GCC komiteen droppede kravet om at GCC
skulle kunne oversættes med en "K&R" (det vil sige pre-C89) compiler.

Nu er GCC i en lidt speciel situation, men det illustrerer at FSF er
ret konservative hvad bagudkompatibilitet angår.

Ukendt (21-06-2004)
Kommentar
Fra : Ukendt


Dato : 21-06-04 23:28

Hej Per.

> Tjah, det var først i 2003 at GCC komiteen droppede kravet om at GCC
> skulle kunne oversættes med en "K&R" (det vil sige pre-C89) compiler.
>
> Nu er GCC i en lidt speciel situation, men det illustrerer at FSF er
> ret konservative hvad bagudkompatibilitet angår.

En af de platforme jeg skriver til kan ikke oversætte GCC nyere end 1.7.2.3
fordi de nyere versioner genererer assembler som min mips assembler ikke
forstår. Og desværre kan binutils heller ikke oversættes her.

Så jeg er nødt til at holde styr på hvor jeg vælger at skrive kode der
benytter de nye faciliteter og hvor jeg holder på backward compatibility.

Der er sket store ting med specielt C++ siden den gang, der er f.eks. ikke
noget STL og namespaces var heller ikke gængs den gang.

Heldigvis er det ikke længere min hovedudviklingsplatform

Med venlig hilsen
Jesper Wolf Jespersen



Søg
Reklame
Statistik
Spørgsmål : 177580
Tips : 31968
Nyheder : 719565
Indlæg : 6409076
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste