|
| 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
| |
|
|