Article View: pl.comp.lang.c
Article #772Re: argv
From: Michal Malecki
Date: Mon, 02 Feb 1998 11:54
Date: Mon, 02 Feb 1998 11:54
124 lines
6936 bytes
6936 bytes
Karpierz <karpierz@inter.intertele.pl> wrote:
: Maciej MOCHOL <mmochol@elka.pw.edu.pl> napisal
:> Prawde mowiac to mi sie juz kompletnie pochrzanilo co jest zgodne
:> ze standardem a co nie. I tak bede robil po swojemu :)
: Tez juz dostalem kociokwiku...
: Dotychczas bylem przekonany ze
: C C++
: 0 argumentow: a (void) a (void) lub a ()
: dowolna ilosc argumentow: a () a (...)
: Jak jest faktycznie, pomocy !
No alescie mi namieszali! Jasna cholera! Az sprawdze jak to sie ma w gcc.
No wiec - nie wiem, jak sie to ma do standardu - sprawa ma sie tak:
Dla C:
Funkcja bez podanej listy parametrow W ZAPOWIEDZI moze byc wywolywana
i deklarowana Z DOWOLNYMI PARAMETRAMI. Wynika to zapewne z tego, ze niegdys
w zapowiedziach ("traditional" czy cos takiego) nie wpisywalo sie parametrow.
Dla C jest bez roznicy, wystarczy, zeby byla zapowiedz. Dopiero jak sie wpisze
konkretna liste parametrow (albo void albo parametry) to wtedy kompilator
moze sie "przypieprzac" do parametrow. Jezeli jednak zadeklarujemy funkcje
z bez listy parametrow, to jezeli nawet w realizacji bedziemy miec
funkcja( const char* t ), a wywolamy funkcja( 2.56 ) to kompilator nawet nie
miauknie. Oczywiscie za skutki musimy winic samych siebie...
Funkcja o zmiennej liscie parametrow w C moze wygladac jak a(). Ale - jak
mowie - w C tak moze wygladac kazda funkcja. Przykladowo printf ma taka
deklaracje:
int printf( const char*, ... );
Jedna wazna cecha funkcje o zmiennej liscie parametrow w C jest to, ze
MUSI wystapic przynajmniej jeden jawny parametr.
Musze wiec niestety przyznac racje, ze funkcja, ktora nie przyjmuje parametrow,
powinna miec w deklaracji void. Na swoja obrone moge powiedziec jedynie, ze
mnie akurat chodzilo o C++. Ja po prostu - o ile sytuacja mnie nie zmusi, jak w
przypadku muda - nie pisze juz nigdy niczego w C. Stad cale nieporozumienie.
Dla C++ wyglada sytuacja w ten sposob:
Funkcja podana w sposobie "a()" jest identyczna z "a( void )". Nie ma
mozliwosci podania dowolnej liczby parametrow. Jest to jedna z najwazniejszych
niezgodnosci pomiedzy C i C++. W C++ kazda funkcja przed wywolaniem musi byc
albo w pelni zdefiniowana, albo chociaz zapowiedziana. Niezapowiedzenie funkcji
w C++ jest bledem. Wynika to z jednej z mozliwosci funkcji w C++ - przecia-
zania. Poniewaz moga byc dwie funkcje o tej samej nazwie, kompilator musi je
rozrozniac.
Jezeli chodzi o zmienna liste parametrow, to w C++ akurat nie musi byc podana
jawnie lista parametrow. Oczywiscie zaleca sie stosowanie makr z stdarg.h,
( a przynajmniej uzywania makra __size ). Niemniej jednak - przykladowo -
jezeli mamy 32-bitowy int i wiemy, ze przekazuje sie jedynie zmienne typu
int lub wskaznikowego, mozemy obslugiwac to w ten sposob:
void funk( ... )
{
int* args = ...;
for ( int i = 0; NIEKONIEC; i++ )
costam( args[i] );
}
Jezeli akurat zdarzy sie nam obslugiwac inne typy, mozemy dokonywac roznych
rzutowan. Jezeli jednak funkcja ma przyjmowac parametry tylko jednego typu,
ewentualnie typy nie szersze, niz int, to mozemy przystac na taka obsluge.
Jezeli np. funkcja ma przyjmowac parametry typu double (obowizaujacy typ
stalych zmiennoprzecinkowych), to deklarujemy sobie tablice:
double* args = ...;
Trzeba tylko pamietac, ze kompilator nie sprawdzi nam poprawnosci wywolania!
Gdyby chciec w ten sposob zadeklarowac funkcje do liczenia - przykladowo -
sredniej arytmetycznej, to musielibysmy wywolywac to tak:
EX( 2.0, 4.0, 6.0, 12.0, 8.0, 0.0, 0.3, -1 );
Na tym koniec dywagacji na temat vararg w C++.
No wiec coz. Jezeli piszemy w C, to jak sie ma funkcje o pustej liscie
parametrow, nalezy pisac void. Inaczej kompilator nie stwierdzi nam
ewentualnego bledu o zlej postaci wywolania funkcji.
Coz moglbym jeszcze dodac... Okazuje sie, ze co i raz dowiaduje sie czegos
nowego o C... jednak skonczyly sie juz czasy, gdy te informacje mialy rowniez
znaczenie dla C++.
:> Przyznam ze najbardziej mnie zaskoczyly te 32KB w standardzie.
: Ja tez zdebialem.. Toby oznaczalo ze jednak standard wspiera
: architekture 16 bitowa... Chyba kilka latek za pozno..
Tia, zgadza sie. I to jest kolejny powod, dla ktorego powinienem zerwac
na zawsze z tym jezykiem.
: Z drugiej strony widzialem w jednym miejscu w kodzie rodem z
: Suna patch zamieniajacy 32767 na 60000...
: Czyzby standard sie juz to jednak zmienil na 64KB ?
Jak juz wczesniej o tym wspominalem, nalezy uzywac dobrych kompilatorow.
Trzeba tutaj rowniez stwierdzic, ze ANSI C to jest MINIMUM! To znaczy, ze
kompilatory musza honorowac owe zapisy. Szkoda tylko, ze jest ich tak malo.
Chwilami nie wiem, czy takie archaiczne zapisy pozostawiono po to, zeby
mozna bylo kompilowac stare programy, czy tez zeby mozna bylo dzis pisane
programy kompilowac na archaicznych kompilatorach. Przy takim rozwoju
informatyki, jaki obserwujemy obecnie uzywanie takich kompilatorow to po
prostu lamerstwo i dziadostwo. Wspolczesnie szanujace sie kompilatory
powinny byc kompilatorami obu jezykow, C i C++. W zwiazku z tym powinny
byc zgodne z ANSI C++. A jezeli kompilator C++ pozwala na takie rzeczy, jak
przydzielanie duzej ilosci pamieci (czy chociazby komentarze C++), to
dlaczego nie mialby na to pozwalac kompilator C ?
No wiec nie wiem. Jezeli ostatni ANSI C pochodzi z 1988 roku - jak to ktos
tutaj sugerowal - to owa data mowi chyba sama za siebie. Rok wczesniej (a
moze nawet w tym samym roku) wyszla River Raid na male atari (i na reszte
"malych" pewnie tez w tym czasie). A wiec ?
A wiec albo C jest juz przestarzaly i nie ma co go uzywac, albo czas na
nowy standard ANSI C.
--
.---. . . - Michal Malecki <mmalecki@technologist.com>/The things that
\___ ,-. | , |- ,-. ,- mUd: zly.mud.org.pl 4000. /can't destroy you
\ |-' |< | | | | uRl: www.kis.p.lodz.pl/~sektor /make you
`---' `-' ' ` `' `-' ' pGp: sektor@zly.kis.p.lodz.pl /stronger...
Technical Details
Message-ID:
<6b4c5g$477@polonez.man.lodz.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!news.nask.pl!ict.pwr.wroc.pl!news.man.lodz.pl!not-for-mailReferences:
<Pine.LNX.3.96.980118170312.17197A-100000@qrnik.knm.org.pl> <34C5278D.10A8@bdk.lublin.pl> <34C5B81A.8C6@imm.org.pl> <Pine.LNX.3.96.980122183153.525B-100000@qrnik.knm.org.pl> <34C8723E.5485@imm.org.pl> <Pine.GSO.3.95.980128131015.7883P-100000@neutron.elka.pw.edu.pl> <01bd2bee$669518e0$90baccc2@karpierz.dyn.ml.org>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!news.nask.pl!ict.pwr.wroc.pl!news.man.lodz.pl!not-for-mail From: Michal Malecki <sektor@zly.kis.p.lodz.pl> Newsgroups: pl.comp.lang.c Subject: Re: argv Date: 2 Feb 1998 11:54:24 GMT Lines: 124 Message-ID: <6b4c5g$477@polonez.man.lodz.pl> References: <Pine.LNX.3.96.980118170312.17197A-100000@qrnik.knm.org.pl> <34C5278D.10A8@bdk.lublin.pl> <34C5B81A.8C6@imm.org.pl> <Pine.LNX.3.96.980122183153.525B-100000@qrnik.knm.org.pl> <34C8723E.5485@imm.org.pl> <Pine.GSO.3.95.980128131015.7883P-100000@neutron.elka.pw.edu.pl> <01bd2bee$669518e0$90baccc2@karpierz.dyn.ml.org> NNTP-Posting-Host: sektor@zly.kis.p.lodz.pl User-Agent: tin/pre-1.4-980105 (UNIX) (SunOS/5.5.1 (i86pc)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit