|
| I tvivl om indlæring af C/C++ Fra : Dan Christensen |
Dato : 29-07-02 21:40 |
|
Hi ng
Jeg er i gang med at lære mig selv c++, har fundet et par online lær dig
selv C++ på 21 dag, og har selv en gammel bog som omhandler c++ men i to af
disse tre læger bøger gør de to af dem meget ud af C og påpeger at det er
bedst at kende grundlæggende c inden man kan programer i C++, men den
sidste bog jeg har er det kun C++ den omtaler c hvor der er nogle
sammenhæng men ellers holdes det hele i c++.
Mit spørgsmål er så er det totalt umuligt at bruge sådanne lære bøger til at
få grundlæggende kendskab til et sprog, og skal jeg bare køre på med at
lære c også selv om det er C++ jeg helst vil lære ??
Til sidst vil jeg blive glad for nogle anbefalinger til c++ bøger gerne
linux for øjet.
Hav lige i tankerne at jeg er total newbi :)
På forhånd tak
/dan
| |
Mogens Hansen (30-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 30-07-02 05:54 |
|
"Dan Christensen" <dan.chr@12move.dk> wrote
> Mit spørgsmål er så er det totalt umuligt at bruge sådanne lære bøger til
at
> få grundlæggende kendskab til et sprog, og skal jeg bare køre på med at
> lære c også selv om det er C++ jeg helst vil lære ??
Nej, hvis du vil lære C++ er der ingen grund til at starte med at lære C
først.
Det er den almindelige anbefaling at man lige så godt kan lære C++ direkte,
og bruge C++ Standard library fra begyndelsen.
Du vil på et tidspunkt komme forbi dele af C, når du lærer C++ - men først
senere.
> Til sidst vil jeg blive glad for nogle anbefalinger til c++ bøger gerne
> linux for øjet.
Et oplagt bud, på en ualmindelig god bog er
Accelerated C++
Andrew Koenig, Barbara E. Moo
ISBN 0-201-70353-X
Idet den behandler Standard C++, er den platform-uafhængig.
Jeg har f.eks. kørt alle eksemplerne ( www.acceleratedcpp.com) på såvel
MS-Windows som Linux, med mange forskellige compilere.
Det betyder naturligvis, at der ikke står noget om hvordan man programmerer
specielle Linux ting som f.eks. KDE eller hvordan man bruger de værktøjer
der findes på en given platform, som f.eks. GCC eller make.
>
> Hav lige i tankerne at jeg er total newbi :)
Det virker som om du allerede har
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (31-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 31-07-02 00:37 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ai55tv$30iu$2@news.cybercity.dk...
> "Dan Christensen" <dan.chr@12move.dk> wrote
> > Mit spørgsmål er så er det totalt umuligt at bruge sådanne lære bøger
til at
> > få grundlæggende kendskab til et sprog, og skal jeg bare køre på med at
> > lære c også selv om det er C++ jeg helst vil lære ??
Det er et spørgsmål der tit er oppe og vende.
Og der er delte meninger.
"Bjarne Stroustrup"-skolen mener at man skal kaste sig lige ud i C++, og at
C er et laverestående sprog som man godt kan undvære.
Andre, inkl. undertegnede, mener at man måske godt kan se nogle "Hello,
World!" eksempler i C++, og også lave en std::string eller to, og måske
ligefrem en std::vector, og sortere den, men hvis man rigtigt vil *forstå*
C++ kan man efter min bedste overbevisning ikke slippe for at lære "C-delen"
af C++ godt at kende (jaja, standardsvaret er at C ikke er en delmængde af
C++, men det vil jeg altså kalde det i praksis).
Et af C++'s vigtigste designkriterier har været binær kompatibilitet med C
(udover "performance for enhver pris"). Derfor kan man ikke forstå C++ uden
at forstå C, IMHO.
Såsnart man skal rode med pointere og referencer (og det er meget svært at
slippe for det i C++), og dermed eksplicit memory-håndtering og styring af
objekt-levetider, så er man ovre i noget at det værste C++ har arvet fra C,
nemlig memory-modellen, eller objekt-modellen, om man vil.
Der er nogle ting som C++ har arvet fra C, som man bare skal vide. "Sådan er
det bare, for at være kompatibelt med C". Lokale variable skaber
stak-objekter, hvis levetid er det scope de er erklæret i. Men man kan
sagtens gemme pointere og referencer længere tid end det, men hvis man
bruger dem til noget, crasher programmet. Det er sådan nogle ting, som
stammer fra C, og som man er nødt til at vide når man programmerer i C++.
> Nej, hvis du vil lære C++ er der ingen grund til at starte med at lære C
> først.
> Det er den almindelige anbefaling at man lige så godt kan lære C++
direkte,
> og bruge C++ Standard library fra begyndelsen.
Det er i hvert fald din almindelige anbefaling . Og Stroustrups. Men ikke
alles.
Man er i hvert fald nødt til at lære så meget C at man kender til begreber
som pointere, stak, heap og objektlevetider. Og typedef, og
memoryallokering/-deallokering. Og så har man stort set lært C.
Så kan du kalde det en del af C++, men fortæl mig så lige hvilken "C-del" af
C++ man kan slippe for at lære (jaja, C-standardlibrariet kan man i høj grad
undvære, hvis det skulle være, men det er ikke selve sproget).
Jeg har desværre set masser af C++ kode der falder i de typiske C++-fælder,
som man ikke opdager hvis man ikke har et godt overblik over den
objekt-model vi har fået af C (scope og objektlevetider, osv.)
Se fx her:
const std::string& Foo::get(const std::string& defaultValue)
{
if (isSet) return myVal;
else return defaultValue;
}
Det ser jo også fint nok ud. Indtil man skriver
const std::string& s = myFoo.get("ups");
Hvor levende er det så lige at 's' er, når vi forventer at den er "ups"?
Mit råd:
Hvis man vil lære C++, er det aldrig spild af tid at blive god til C også,
da det i praksis er en fin, velafgrænset delmængde af C++. Jeg siger "i
praksis", fordi kværulanterne mener at vide at der kan frembringes eksempler
på gyldig C-kode, der ikke er gyldig C++-kode. [Læs: det ved jeg godt, men
det er ikke nogle detaljer at distrahere en begynder med.]
I stedet for at bruge "char*", strcpy, FILE*, printf, osv. (dvs. C's
standard-bibliotek), kan det dog være en god ide at koncentrere sig om C++'s
standardbibliotek, for overhovedet at komme nogen vejne - C++-standardlib'et
giver nogle implementationer af praktiske højniveaustrukturer
og -algoritmer - i hvert fald når man er "øvet nok" til at styre uden om
alle de typiske fælder. Og hvis man kender et passende stort arsenal af
idiomer til at løse typiske problemer med.
Hvis du (Dan) aldrig har programmeret før, er C/C++ en stor kamel at sluge.
Hvad der ellers kan være et godt begyndersprog har været diskuteret til
hudløshed i dk.edb.programmering - kig evt. tilbage i gamle indlæg der :)
Bjarke
| |
Jakob Møbjerg Nielse~ (31-07-2002)
| Kommentar Fra : Jakob Møbjerg Nielse~ |
Dato : 31-07-02 10:41 |
|
Bjarke Dahl Ebert wrote:
> Man er i hvert fald nødt til at lære så meget C at man kender til
> begreber som pointere, stak, heap og objektlevetider. Og typedef, og
> memoryallokering/-deallokering. Og så har man stort set lært C.
Nu tilhører disse ting jo netop også C++, så i stedet for at sige at man
stort set har lært C, kan man jo sige at man har lært noget af det
grummeste C++ har at byde på. Jeg kan ikke se hvorfor det er så
nødvendigt at forklare at disse ting også findes i C, det opdager
læseren nok på et tidspunkt.
--
Jakob Møbjerg Nielsen | "Five exclamation marks, the
jakob@dataloger.dk | sure sign of an insane mind."
http://www.jakobnielsen.dk/ | -- Terry Pratchett, Reaper Man
| |
Bjarke Dahl Ebert (31-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 31-07-02 14:20 |
|
"Jakob Møbjerg Nielsen" <jakob@dataloger.dk> wrote in message
news:ai8ba4$cls$1@sunsite.dk...
> Bjarke Dahl Ebert wrote:
> > Man er i hvert fald nødt til at lære så meget C at man kender til
> > begreber som pointere, stak, heap og objektlevetider. Og typedef, og
> > memoryallokering/-deallokering. Og så har man stort set lært C.
>
> Nu tilhører disse ting jo netop også C++, så i stedet for at sige at man
> stort set har lært C, kan man jo sige at man har lært noget af det
> grummeste C++ har at byde på.
Jamen, selvom det er noget af det rigtig grumme i C++, så kan man ikke bare
ignorere det. Man kan ikke slå det fra - desværre. Hvis man ignorerer
begrebet "objektlevetid", bliver man alligevel før eller siden tvunget til
at tage stilling til det.
> Jeg kan ikke se hvorfor det er så
> nødvendigt at forklare at disse ting også findes i C, det opdager
> læseren nok på et tidspunkt.
Jojo, jeg siger heller ikke at man behøver at forklare hvad der er C++ og
hvad der er ren C (men hvorfor skulle man dog ikke det - det koster da ikke
noget).
Jeg siger bare at der ikke er ret meget i C, som man kan slippe for at vide
i C++.
Bjarke
| |
Jakob Møbjerg Nielse~ (31-07-2002)
| Kommentar Fra : Jakob Møbjerg Nielse~ |
Dato : 31-07-02 17:54 |
|
Bjarke Dahl Ebert wrote:
> Jamen, selvom det er noget af det rigtig grumme i C++, så kan man
> ikke bare ignorere det.
Det sagde jeg bestemt heller ikke at man kan.
> Jojo, jeg siger heller ikke at man behøver at forklare hvad der er
> C++ og hvad der er ren C (men hvorfor skulle man dog ikke det - det
> koster da ikke noget).
Fordi det er lige så meget C++ som det er C. Og for ikke at forvirre
læseren.
> Jeg siger bare at der ikke er ret meget i C, som man kan slippe for
> at vide i C++.
Nej, for de deler mange principper og meget syntaks, men derfor synes
jeg stadig at man skal adskille C++ og C, og ikke snakke om hvad der
kommer fra C. Det virker underligt at lære C fra en C++ bog.
--
Jakob Møbjerg Nielsen | "Five exclamation marks, the
jakob@dataloger.dk | sure sign of an insane mind."
http://www.jakobnielsen.dk/ | -- Terry Pratchett, Reaper Man
| |
Mogens Hansen (31-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 31-07-02 21:58 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote
> > "Dan Christensen" <dan.chr@12move.dk> wrote
[snip]
> Og der er delte meninger.
Naturligvis.
> "Bjarne Stroustrup"-skolen mener at man skal kaste sig lige ud i C++, og
at
> C er et laverestående sprog som man godt kan undvære.
Hvorfra har du at " "Bjarne Stroustrup"-skolen mener at C er et
laverestående sprog som man godt kan undvære" ?
Det vil undre mig, hvis det er fra Bjarne Stroustrup - så havde der nok ikke
været så meget fokus på source-kode kompatibilitet..
Se f.eks.
http://www.cuj.com/articles/2002/0207/0207d/0207d.htm?topic=reference
http://www.cuj.com/articles/2002/0208/0208c/0208c.htm?topic=reference
for at se at du åbenlyst tager fejl.
[snip]
> ..., men hvis man rigtigt vil *forstå*
> C++ kan man efter min bedste overbevisning ikke slippe for at lære
"C-delen"
> af C++ godt at kende
Det er vi enige om, og det var også det jeg sagde i mit oprindelige svar:
"Du vil på et tidspunkt komme forbi dele af C, når du lærer C++ - men først
senere."
Bogen "Accelerated C++" er et glimrende eksempel på den tilgang til C++ - og
jeg _ved_ at mange har haft glæde af at lære C++ på den måde.
Den starter med forholdvis høj-niveau konstruktioner som er sikre, og
bevæger sig herefter nedad - i stedet for at gøre det modsat.
Men der findes naturligvis ikke _een_ måde som er optimal for _alle_.
[snip]
> Et af C++'s vigtigste designkriterier har været binær kompatibilitet med C
C og C++ standarder beskæftiger sig slet ikke med binær kompatibilitet.
Binær kompabilitet anses for at være et platform specifikt spørgsmål.
C++ beskæftiger sig med source-kode kompatibilitet med C.
[snip]
> > Nej, hvis du vil lære C++ er der ingen grund til at starte med at lære C
> > først.
> > Det er den almindelige anbefaling at man lige så godt kan lære C++
> direkte,
> > og bruge C++ Standard library fra begyndelsen.
>
> Det er i hvert fald din almindelige anbefaling . Og Stroustrups. Men
ikke
> alles.
Naturligvis - det ville være underligt, hvis _alle_ var enige om det.
Omvendt er vi nok ikke de eneste - vi er formodentlig i flertal, blandt dem
der kender reelt C++ (og jeg prøver ikke at sige at du ikke kender C++).
> Man er i hvert fald nødt til at lære så meget C at man kender til begreber
> som pointere, stak, heap og objektlevetider. Og typedef, og
> memoryallokering/-deallokering. Og så har man stort set lært C.
Der er vist ingen i denne tråd, der har sagt at man ikke skal lære noget om
pointere, stak, heap og objektlevetider - det er jo en væsentlig del af C++.
Den bog jeg anbefalede behandler naturligvis disse emner. Blot ikke som det
første, og ikke inden der bliver lavet nyttige programmer.
> Så kan du kalde det en del af C++, men fortæl mig så lige hvilken "C-del"
af
> C++ man kan slippe for at lære (jaja, C-standardlibrariet kan man i høj
grad
> undvære, hvis det skulle være, men det er ikke selve sproget).
Det vigtigste er nok kode stilen, som er forskellig.
Meget af standard biblioteket kan man slippe for.
Hvor man i C bruger strcpy, malloc og printf, vil man oftest i C++ bruge
std::string, new og stream biblioteket.
En del (det meste) af brugen af preprocessoren kan man slippe for.
Og jo, standard biblioteket i såvel C som C++ _er_ en del af selve sproget -
det står i de samme standarder.
Der er en skelnen mellem "core language" og "standard library", men begge
dele er med i sprogene.
> Jeg har desværre set masser af C++ kode der falder i de typiske
C++-fælder,
> som man ikke opdager hvis man ikke har et godt overblik over den
> objekt-model vi har fået af C (scope og objektlevetider, osv.)
Det er ofte fordi man ikke bruger værktøjer, der hjælper een med at finde
den slags problemer.
Jeg opfordrer altid folk til at bruge værktøjer som CodeGuard,
BoundsChecker, Purify, Valgrind eller hvad der nu findes på ens platform til
at finde den slags problemer.
Dels gør det konkret programmet bedre, og dels uddanner det programmørerne
til bedre at forstå f.eks. objektlevetider.
[snip]
> Mit råd:
> Hvis man vil lære C++, er det aldrig spild af tid at blive god til C også,
> da det i praksis er en fin, velafgrænset delmængde af C++.
Nej, det er bestemt nyttigt at kende mange andre sprog.
Der er mange ting der ikke er spild - men vi har alle begrænsede resource,
så der må prioriteres.
Hvis målet er at lære C++, er det ubetinget en omvej at lære C først. Ikke
at det er spild, men dog en omvej.
Det er ikke spild at lære hvad der sker inde i C++, sådan som det er
beskrevet i
Inside the C++ Object Model
Stanley B. Lippman
ISBN 0-201-83454-5
men det er ikke nødvendigt for at komme i gang med at lære C++.
Spørgsmålet er hvor man skal starte - og ikke se meget hvor man skal
slutte.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (31-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 31-07-02 23:48 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ai9imi$2cqt$1@news.cybercity.dk...
> Hvorfra har du at " "Bjarne Stroustrup"-skolen mener at C er et
> laverestående sprog som man godt kan undvære" ?
Jaja, lidt firkantet stillet op
De mener at man skal bruge C++ som et selvstændigt sprog og glemme C, eller
anse C som deprecated når vi har C++.
Jeg mener at man I praksis ikke kan undvære at vide en hel masse om C, når
man programmerer i C++.
Ellers vil man fx blive meget forvirret over linker-fejlmeddelelser.
Jeg hører tit "det compilerer ikke", når det i virkeligheden er linkeren der
brokker sig. Det er kun folk der ikke fatter C, der kan sige sådan.
Og, ja, så kan man sige at det ikke har noget med C at gøre, men er en del
af C++.
Men det er et spørgsmål om ord. For mig at se at det "C-delen af C++" der er
på spil.
Jeg tror ikke på at det er specielt sundt at se C++ som ét sammenhængende
sprog. En stor del af sproget er *direkte* arvet fra C.
Hvis C++ ikke skulle være kompatibelt med C, ville det have set meget
anderledes ud. (Det indrømmer Stroustrup også selv).
> > ..., men hvis man rigtigt vil *forstå*
> > C++ kan man efter min bedste overbevisning ikke slippe for at lære
"C-delen"
> > af C++ godt at kende
> Det er vi enige om, og det var også det jeg sagde i mit oprindelige svar:
> "Du vil på et tidspunkt komme forbi dele af C, når du lærer C++ - men
først
> senere."
Ja, så kan man diskutere hvor mange timer der går før man er nødt til at
forklare hvad en pointer er.
Det kalder jeg C, du kalder det en del af C++. Jeg kan ikke se den store
forskel i praksis.
> Bogen "Accelerated C++" er et glimrende eksempel på den tilgang til C++ -
og
> jeg _ved_ at mange har haft glæde af at lære C++ på den måde.
Det er da muligt.
Jeg selv ville nødigt lære et nyt sprog uden at starte med en introduktion
til objekt-modellen i sproget. Dvs., hvad er en variabel, hvad er et objekt,
hvad er en type, hvad er scope/levetid af objekter, har man call by value
eller call by reference, eller noget andet, osv.
Hvis man er helt ny indenfor programmering, ved man nok alligevel ikke hvad
ovenstående er, og så skal man naturligvis starte med "bare noget".
> > Et af C++'s vigtigste designkriterier har været binær kompatibilitet med
C
> C og C++ standarder beskæftiger sig slet ikke med binær kompatibilitet.
ISO C++ standarden har på formidabel vis "snydt" sig udenom real-world
issues som fx binære interfaces og tråde.
Der er dog visse ting i standarden der hælder binære issues ind ad bagdøren.
For såkaldte "POD objects" (C++-folkloren vil vide at det er Plain Old Data)
er der strikse regler for semantikken af pointer-casts mellem "kompatible
structs". Hvis standard-kommiteen ikke her har haft praktiske, binære
implementationer i baghovedet, så må du kalde mig Stroustrup.
Desuden nævnte jeg slet ikke standarder. Jeg talte om C++'s designkriterer.
Design og standard er to meget forskellige ting. Bild mig ikke ind at man
ikke har *ønsket* binær kompatibilitet mellem C og C++ (hvorfor skulle man
ellers lave visse ting så åndssvagt i C++ som tilfældet er), og at det har
været et ufravigeligt krav at kunne tilbyde dette. Standarden er tydeligvis
tilrettelagt på implementationer der er binært kompatible med C - også
selvom de ikke nævner det eksplicit.
> Binær kompabilitet anses for at være et platform specifikt spørgsmål.
> C++ beskæftiger sig med source-kode kompatibilitet med C.
Ja, standarden gør. Men jeg er slet ikke så fokuseret på standarden, men
derimod hvad der er muligt i praksis. I praksis er C++-implementationer mere
ens end standarden kræver. Der er et mismatch mellem den (misforståede?)
frihed som standarden trods alt giver, og hvad der findes af
implementationer.
> Der er vist ingen i denne tråd, der har sagt at man ikke skal lære noget
om
> pointere, stak, heap og objektlevetider - det er jo en væsentlig del af
C++.
> Den bog jeg anbefalede behandler naturligvis disse emner. Blot ikke som
det
> første, og ikke inden der bliver lavet nyttige programmer.
Man får meget hurtigt brug for pointere. Alternativet er at funktioner der
returnerer komplekse strukturer, skal returnere fx en std::map eller
std::list by value. Det har man ikke lyst til i ret lang tid.
> En del (det meste) af brugen af preprocessoren kan man slippe for.
Ja, okay. Det er jeg meget enig i.
Man kan bruge C++ i lang tid, før man vil få brug for (læs: blive nødt til)
at bruge makroer.
> Og jo, standard biblioteket i såvel C som C++ _er_ en del af selve
sproget -
> det står i de samme standarder.
> Der er en skelnen mellem "core language" og "standard library", men begge
> dele er med i sprogene.
Det er klart.
Men det er også sundt lige fra starten at skelne mellem "core language" og
"library".
Det er godt at vide at cout ikke er et keyword, selvom det godt kan se sådan
ud, for nu at tage et banalt eksempel
> > Jeg har desværre set masser af C++ kode der falder i de typiske
> C++-fælder,
> > som man ikke opdager hvis man ikke har et godt overblik over den
> > objekt-model vi har fået af C (scope og objektlevetider, osv.)
> Det er ofte fordi man ikke bruger værktøjer, der hjælper een med at finde
> den slags problemer.
> Jeg opfordrer altid folk til at bruge værktøjer som CodeGuard,
> BoundsChecker, Purify, Valgrind eller hvad der nu findes på ens platform
til
> at finde den slags problemer.
Ja - det er faktisk fine værktøjer. Det sørgelige er at der er brug for dem.
Man burde have en compile-time option der kompilerede alle relevante checks
ind i koden i debug-udgave. Problemet er igen, at så ødelægger man det
binære interface (kald-konventionerne, struct layout, osv). Jeg ved godt at
kaldkonventioner ikke er en del af standarden, men et sprog er altså meget
mere end standarden (ellers ville man jo helt ignorere ting som kodestil,
design, idiomer, og "miljøet").
En C++ compiler der outputter kode der ikke kan linke med defacto-libfiler
(.LIB og .DLL under Windows, .a og .so under Unix), ville ikke have mange
chancer.
Så kan du sige alt det du vil at binært interface ikke beskrives i den
officielle C++-standard, men der findes altså en defacto-standard for
hvordan kompileret kode taler med hinanden.
Mvh. Bjarke
| |
Bjarke Dahl Ebert (01-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 01-08-02 00:32 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message news:QPZ19.552
> Der er dog visse ting i standarden der hælder binære issues ind ad
bagdøren.
> For såkaldte "POD objects" (C++-folkloren vil vide at det er Plain Old
Data)
> er der strikse regler for semantikken af pointer-casts mellem "kompatible
> structs". Hvis standard-kommiteen ikke her har haft praktiske, binære
> implementationer i baghovedet, så må du kalde mig Stroustrup.
Jeg fandt lige følgende (fra
http://www-cpd.fnal.gov/personal/wb/boost/ISOcxx/doc/POD.html).
Hvis det ikke i praksis restringerer C++-implementationer til at være binært
kompatible med C (eller i det mindste, at gøre tingene på C-manér, og
hvorfor så ikke være kompatibel), så ved jeg ikke hvad.
Mvh. Bjarke
----------------------------------
Layout
The bytes constituting a POD object are contiguous [§1.8, ¶5].
"POD-struct ... types are layout-compatible if they have the same number of
members, and corresponding members (in order) have layout-compatible types"
[§9.2, ¶14].
POD-union ... types are layout-compatible if they have the same number of
members, and corresponding members (in any order) have layout-compatible
types" [§9.2, ¶15].
Initialization
A non-const POD object declared with no initializer has an "indeterminate
initial value" [§8.5, ¶9].
Default initialization of a POD object is zero initialization [§8.5, ¶5].
A static POD object declared with an initializer is given its initial value:
if local, "before its block is first entered" [§6.7, ¶4]; else
if non-local, "before any dynamic initialization takes place" [§3.6.2, ¶1].
Copying
The bytes constituting a POD object can be copied (e.g., via memcpy()) to a
sufficiently large array of char or unsigned char and back again without
changing the object's value [§3.9, ¶2], or to another object of the same
POD-type, in which case the second object's value will be the same as that
of the first [§3.9, ¶3].
[...snip...]
Addressing
The address of a POD object can be an address constant expression (or part
of one) [§5.19, ¶4], while a reference to a POD member can be a reference
constant expression [§5.19, ¶5].
"A pointer to a POD-struct object, suitably converted using a
reinterpret_cast, points to its initial member ... and vice versa" [§9.2,
¶17].
----------------------------------
| |
Mogens Hansen (01-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 01-08-02 16:46 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote
>
> > Hvorfra har du at " "Bjarne Stroustrup"-skolen mener at C er et
> > laverestående sprog som man godt kan undvære" ?
>
> Jaja, lidt firkantet stillet op
>
> De mener at man skal bruge C++ som et selvstændigt sprog og glemme C,
eller
> anse C som deprecated når vi har C++.
Objektivt set _er_ C++ et selvstændigt sprog, der er defineret i standarden
"ISO/IEC 14882:1998(E)".
Hvor, i det miljø du kalder "Bjarne Stroustrup-skolen", har du udsagnet "De
anser C som deprecated når vi har C++" fra ?
Fra Bjarne Stroustrup ?
Jeg har spurgt een gang, men du snakker udenom, og kommer blot med flere
udokumenterede påstande.
Du må da kunne fortælle hvad der er din kilde.
Det oprindelige spørgsmål var "...skal jeg bare køre på med at lære c også
selv om det er C++ jeg helst vil lære ??"
Hvis man vil vide, hvad Bjarne Stroustrup mener om det spørgsmål, kan man se
http://www.research.att.com/~bs/bs_faq.html#prerequisite
Der står så vidt jeg kan se ikke noget med:
* at C er et laverestående sprog som man godt kan undvære
* at C anses for deprecated når vi har C++
sådan som du påstår at "Bjarne Stroustrup-skolen" mener.
Du tager simpelthen fejl.
Bjarne Stroustrups anbefaling svarer, så vidt jeg kan se, fuldstændig til
hvad jeg sagde i mit oprindelige svar til Dan Christensen.
Det gælder også anbefalingen af "Accelerated C++" som et eksempel på
indlæring af moderne C++ uden at starte med C.
Bemærk at jeg anbefalede bogen allerede for 2 år siden - altså inden den var
udkommet - på denne nyhedsgruppe.
Det er min egen personlige anbefaling, og ikke blot en afskrift af Bjarne
Stroustrup - jeg var faktisk ikke klar over at han nævnte den på det sted
før nu.
> Jeg mener at man I praksis ikke kan undvære at vide en hel masse om C, når
> man programmerer i C++.
Er der nogen i denne tråd der har påstået det ?
Man kan kan godt lære om pointere, automatiske variable, heap variable etc.
fordi det er en del af C++, uden at vide at det stammer fra C.
[snip]
> Ja, så kan man diskutere hvor mange timer der går før man er nødt til at
> forklare hvad en pointer er.
> Det kalder jeg C, du kalder det en del af C++. Jeg kan ikke se den store
> forskel i praksis.
Nej, jeg kan heller ikke se den store forskel på det punkt.
Jeg er i tvivl om hvad det er for et budskab du ønsker at få igennem til Dan
Christensen.
> > Bogen "Accelerated C++" er et glimrende eksempel på den tilgang til
C++ - og
> > jeg _ved_ at mange har haft glæde af at lære C++ på den måde.
>
> Det er da muligt.
> Jeg selv ville nødigt lære et nyt sprog uden at starte med en introduktion
> til objekt-modellen i sproget. Dvs., hvad er en variabel, hvad er et
objekt,
> hvad er en type, hvad er scope/levetid af objekter, har man call by value
> eller call by reference, eller noget andet, osv.
Det kan jeg da godt forstå.
Du virker som om at du antager at "Accelerated C++" ikke beskriver disse
ting.
Typer bliver beskrevet på side 4, scope på side 5, variabel på side 10,
objektlevetiden på side 15 og "call by value" side 53 og "call by reference"
på side 56.
Kender du overhovedet "Accelerated C++" ?
[snip]
> Standarden er tydeligvis
> tilrettelagt på implementationer der er binært kompatible med C - også
> selvom de ikke nævner det eksplicit.
Naturligvis er det med vilje at C++ arbejder godt sammen med C binært, på en
given platform.
Det er blot ikke sprogene, der definerer det binære interface.
Det er den givne platform, der definerer defacto standarden (eller mere
formelt som f.eks. ABI til Itanium eller gcc 3.x) for ting som:
* kaldekonvention
* alignment
* størrelsen på visse typer
* hvilke typer, der forventes at være binære kompatible mellem compilere
og compilerversioner
[snip]
> > Der er vist ingen i denne tråd, der har sagt at man ikke skal lære noget
om
> > pointere, stak, heap og objektlevetider - det er jo en væsentlig del af
C++.
> > Den bog jeg anbefalede behandler naturligvis disse emner. Blot ikke som
det
> > første, og ikke inden der bliver lavet nyttige programmer.
>
> Man får meget hurtigt brug for pointere. Alternativet er at funktioner der
> returnerer komplekse strukturer, skal returnere fx en std::map eller
> std::list by value. Det har man ikke lyst til i ret lang tid.
Hvorfor har man ikke lyst til det ?
Ofte vil "return value optimization" sikre, at der ikke bliver lavet de
ekstra kopier af objekter som man frygter.
Alternativt kan man overføre den container, hvor resultatet skal gemmes by
reference - sådan som det vises i "Accelerated C++" på side 56, i kapitlet
"Organizing programs and data".
> Det er klart.
> Men det er også sundt lige fra starten at skelne mellem "core language" og
> "library".
Enig.
"Accelerated C++" beskriver det øverst på side 2.
> Det er godt at vide at cout ikke er et keyword, selvom det godt kan se
sådan
> ud, for nu at tage et banalt eksempel
Enig.
Og vide at man skal includere noget for at bruge "cout", men ikke for at
lave en "while" løkke.
"Accelerated C++" beskriver det øverst på side 2.
[snip]
> Ja - det er faktisk fine værktøjer. Det sørgelige er at der er brug for
dem.
Det kan man sige om alle (gode) debug værktøjer generelt - f.eks. ens
interaktive debugger og fejlmeldingerne fra compileren.
[snip]
> Man burde have en compile-time option der kompilerede alle relevante
checks
> ind i koden i debug-udgave.
Det er eksakt hvad CodeGuard gør (for en passende bred definition af "alle
relevante checks").
Det er også hvad instrumenteringsdelen af BoundsChecker gør sammen med
Visual C++ V6.0 (dog efter min erfaringer for en lidt smallere definition af
"alle relevante checks"):
> Problemet er igen, at så ødelægger man det
> binære interface (kald-konventionerne, struct layout, osv).
Det gør CodeGuard og BoundsChecker ikke.
> Jeg ved godt at
> kaldkonventioner ikke er en del af standarden, men et sprog er altså meget
> mere end standarden (ellers ville man jo helt ignorere ting som kodestil,
> design, idiomer, og "miljøet").
Nemlig.
Kodestil, design, idiomer og miljøet er væsentlig forskel mellem C og C++.
> En C++ compiler der outputter kode der ikke kan linke med defacto-libfiler
> (.LIB og .DLL under Windows, .a og .so under Unix), ville ikke have mange
> chancer.
Der er en væsentlig forskel, i denne sammenhæng, mellem .LIB og .DLL.
..LIB filer er et intern anliggende, for en given compiler i en given
version.
..DLL filer er et interface til færdige komponenter på Windows platformen.
Man kan ikke forvente at man frit kan bruge .LIB filer lavet med een
compiler, sammen med en anden compiler.
En C++ (eller C) compiler til MS-Windows må forventes at kunne tilgå .DLL'er
med C funktioner, med de typer der er gyldige for platformen.
Det er f.eks. ikke tilladt at bruge "long double" på sådan en grænseflade,
hvis man har en forventning om at det skal virke generelt, selvom det er en
standard C type.
> Så kan du sige alt det du vil at binært interface ikke beskrives i den
> officielle C++-standard, men der findes altså en defacto-standard for
> hvordan kompileret kode taler med hinanden.
Har jeg sagt andet ?
Det er formodentlig med vilje, at C++ Standarden ikke standardiserer binære
interfaces, for at give de enkelte implementeringer frihed til at lave en
god løsning.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (01-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 01-08-02 23:22 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aibkq3$1l5n$1@news.cybercity.dk...
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> > De mener at man skal bruge C++ som et selvstændigt sprog og glemme C,
eller
> > anse C som deprecated når vi har C++.
> Objektivt set _er_ C++ et selvstændigt sprog, der er defineret i
standarden
> "ISO/IEC 14882:1998(E)".
Det ved vi jo godt - dig og din standard .
Du var jo selv enig i at et sprog er meget mere end det, ikke?
> Hvor, i det miljø du kalder "Bjarne Stroustrup-skolen", har du udsagnet
"De
> anser C som deprecated når vi har C++" fra ?
Det var ikke et citat, det var min vurdering.
Men hvis du vil have en reference, så kan det vel ikke udtrykkes klarere end
Stroupstrup himself gør det i sin klassiske artikel,
http://www.research.att.com/~bs/new_learning.pdf, om hvordan man bør lære
C++, og puttet ind mellem linierne, hvorfor C++ er så "fedt".
Han spilder det meste af artiklen på at fortælle hvorfor man ikke skal
skrive i C-stil, men hellere C++-stil. Hans motiveringer for C++-stilen
viser allerhøjst at C++ har nogle fordele som man mangler i C. Men alle hans
motiver passer på mange andre sprog (og passer ofte bedre).
Han bruger slagord som Simplicity, Expressiveness og Correctness. Han viser
så eksempler på ting der kan gå galt i C, og viser hvor "error-prone" C er,
hvor det angiveligt skulle fungere meget bedre i C++. Det kan jeg bare ikke
tage alvorligt. Hvis der er noget C++ er mester i, så er det "gæt hvad dette
kode gør" semantik. Og ved at arve C's memorymodel, så er man da sikker på
at skabe debugging-mareridt (som gør at Rational kan score kassen på
Purify).
Disse kriterier (Simplicity, osv) han opremser mener jeg faktisk opfyldes
*bedre* af de fleste moderne programmeringssprog end af C++.
Kun én ting må jeg medgive ham: C++'s performance er sgu svær at slå. (Men
det er jo klart når det er en kæmpe Mother Assembler )
> Jeg har spurgt een gang, men du snakker udenom, og kommer blot med flere
> udokumenterede påstande.
Jeg troede ikke at det var et forhør.
> Du må da kunne fortælle hvad der er din kilde.
Som sagt var det ikke et citat, men min personlige vurdering.
Min kilde er derfor bøger (skrevet af begejstrede C++-brugere, der nok skal
blive omvendt en dag hvis de tør give andre, mere moderne sprog en chance),
Usenet (fx comp.lang.c++.moderated), CUJ, og programmører jeg taler med.
Det jeg kalder Stroustrup-skolen, er dem der bruger C++ fordi de er
overbeviste om at det er det bedste sprog til de fleste opgaver, og at C++
har en stor fremtid. De er specielt begejstrede for templates og alt hvad de
indebærer. Når de støder på et af de mange problemer, bagateliserer de det
med at det ikke er C++'s skyld, eller at det problem kender de godt, og kan
også give en god forklaring på hvorfor C++ har det problem, og det skal nok
blive løst i næste standard eller næste igen, eller også findes der allerede
et eller andet work-around der kan klare det.
Uden at kende dig ret godt, og ikke for at putte folk i kasser, men jeg vil
skyde på at du tilhører den gruppe ;).
> Det oprindelige spørgsmål var "...skal jeg bare køre på med at lære c også
> selv om det er C++ jeg helst vil lære ??"
Ja, og det er vel også ca det der har været diskuteret.
Jeg mener: Ja, hvorfor ikke lære C *også* (som der står)? Det skader ikke,
og man skal alligevel lære næsten alt hvad der er værd at vide om C (bortset
fra standardlibrariet) for at kunne begå sig i C++.
> Hvis man vil vide, hvad Bjarne Stroustrup mener om det spørgsmål, kan man
se
> http://www.research.att.com/~bs/bs_faq.html#prerequisite
Man skal ikke lytte til Stroustrup . Han er en bitter gammel mand der er
sur på Java og Microsoft
> Der står så vidt jeg kan se ikke noget med:
> * at C er et laverestående sprog som man godt kan undvære
> * at C anses for deprecated når vi har C++
> sådan som du påstår at "Bjarne Stroustrup-skolen" mener.
Nej, ikke lige dér.
Nu vi har fat i Dr. Stroustrups FAQ, så lad mig lige svare på de ting han
skriver under "Knowing C is a prerequisite for learning C++, right?":
DrStr> The common subset of C and C++ is easier to learn than C
Forkert.
"The common subset of C and C++" er stort set hele C. Der er lige nogle
issues med at "int" er default i C nogle steder hvor det ikke er det i C++,
og så er der også lige nogle conversion-regler der er lidt anderledes. Og
"class", "template", "explicit", "throw" osv. er ikke keywords i C, og kan
derfor bruges som identifiers. Det er stort set det.
DrStr> There will be less type errors to catch manually
Vrøvl. C++ har præcis de samme problemer med at ting er lovlige som ikke
burde være det. (man kan stadig caste en pointer til en double - det er
noget der hører assemblerprogrammering til). Det er ikke nok at sige at man
bare kan lade være med at bruge det. Når det drejer sig om fejldetektion,
har man ofte at "more is less". Ting som man ikke bruger, gør pludselig
programfejl til "lovlig kode". Dette gælder fx også funktionsoverloading -
her kan man heller ikke bare sige, "så lad være med at bruge det", for hvis
jeg definerer en funktion der ikke matcher sin prototype, så er det jo bare
en overloaded funktion.
DrStr> the C++ type system is stricter and more expressive
Stricter - nej. Det eneste der er stricter, er at konvertering fra "void*"
til "Foo*" kræver en eksplicit cast, det gør det ikke i C. Men det er
sikkert fordi hr Stroustrup ellers ikke kunne finde ud af at skrue
overload-reglerne ordentligt sammen (de er komplicerede nok i forvejen).
More expressive - tja, man har nedarvning og templates. Brugere af mere
moderne sprog vil i bedste fald finde påstanden om expressiveness i C++ en
dårlig vittighed.
DrStr> fewer tricks to learn
SAY WHAT???
DrStr> and better libraries available
Okay, det kan jeg godt give ham ret i. Men de er stadig svære at bruge. Selv
meget øvede C++-programmører kager jævnligt rundt i STL-algoritmer og
binders, osv. Og det er nemt at få koden til at gå i stykker, uden brugbar
"diagnostics". Det er fordi C++ sætter performance over alt andet - i den
forstand at når der har været et valg mellem to mulige måder at designe
sproget på, har det altid være performance-issues der afgjorde valget. Det
er udmærket til nogle få ting, men til de fleste ting er performance langt
fra det vigtigste.
> Jeg er i tvivl om hvad det er for et budskab du ønsker at få igennem til
Dan
> Christensen.
Så er det da godt at du ikke er Dan Christensen
Her er budskabet: "Det er *udmærket* at lære både C og C++. Gerne i den
rækkefølge, men også gerne samtidigt, da C++ i praksis er C plus ekstra
features".
Mit lidt mere skjulte budskab er at C++ er noget skrammel
> Du virker som om at du antager at "Accelerated C++" ikke beskriver disse
> ting.
> Typer bliver beskrevet på side 4, scope på side 5, variabel på side 10,
> objektlevetiden på side 15 og "call by value" side 53 og "call by
reference"
> på side 56.
> Kender du overhovedet "Accelerated C++" ?
Nej, burde jeg det?
Det er længe siden jeg har haft behov for en lærebog i C++, så jeg kender
ikke ret mange af slagsen. Jeg har Stroustrups C++-bibel, 3rd edition. Hans
spredt-over-bogen motiverende forklaringer ("undskyldninger" var efter
min mening relevante i starten af 90'erne. Udviklingen i teknologi og mere
udtryksfulde sprog har siden overhalet C++ indenom.
> Det er blot ikke sprogene, der definerer det binære interface.
> Det er den givne platform, der definerer defacto standarden (eller mere
> formelt som f.eks. ABI til Itanium eller gcc 3.x) for ting som:
> * kaldekonvention
> * alignment
> * størrelsen på visse typer
> * hvilke typer, der forventes at være binære kompatible mellem compilere
> og compilerversioner
Ja, men det er
* kaldekonventioner for C-funktioner
* alignment for C-strukturer
* størrelsen af integral types i C
* kompatibilitet af C-typer.
Det er specielt ikke
* kaldekonventioner for O'Caml-funktioner
* alignment for O'Caml-strukturer
* størrelsen af integral types i O'Caml
* kompatibilitet af O'Caml-typer.
Kan du se hvor jeg vil hen? Det er ligegyldigt at disse ting ikke nævnes i
ISO/IEC 14882:1998(E). De er en del af sproget, fordi der er etableret
defacto-konventioner omkring disse ting.
C++ benytter (ikke i din ISO/IEC 14882:1998 men i den virkelige verden) alle
disse C-konventioner direkte - dog bruger man "mangled names" for at hacke
funktionsprototyper ned i noget der minder om en C-identifier, for at kunne
få overloading uden at droppe C-linkeren.
(For at komme gentagne svar i forkøbet: jeg ved godt at der typisk følger en
C++-linker med, men det er oftest under lakken blot en C-linker, der kan
demangle navne, og skippe redundante instantieringer af templates og
inlinefunktioner).
> > Man får meget hurtigt brug for pointere. Alternativet er at funktioner
der
> > returnerer komplekse strukturer, skal returnere fx en std::map eller
> > std::list by value. Det har man ikke lyst til i ret lang tid.
> Hvorfor har man ikke lyst til det ?
Fordi disse strukturer har det med at være enten for tunge at kopiere, eller
"ukopierbare". Nogle ting kan bare ikke håndteres by value.
> Ofte vil "return value optimization" sikre, at der ikke bliver lavet de
> ekstra kopier af objekter som man frygter.
Meget sjældent, vil jeg mene. Den optimering har kun lov til at
bort-optimering af kopiering af det udtryk der står efter return.
Så, simpelt eksempel:
std::set<MyClass, MyComparator> mkTestSet()
{
std::set<MyClass, MyComparator> result;
result.insert(someObject);
result.insert(otherObject);
return result;
}
Ingen optimering her. Og det er det typiske tilfælde. Der hvor optimeringen
hjælper, er på banale funktioner som "std::string foo() { return strA +
strB; }". Så får man konstrueret sin streng-sum direkte i returobjektet.
std::auto_ptr bliver man også ked af i længden, for den fungerer kun når
"reference-ejerskabsforhold" er simple nok til at en auto_ptr kan håndtere
det. Man kan fx ikke engang have en std::vector<std::auto_ptr<Foo> >.
Nåja, så skal man også lige huske mellemrummet mellem de to sidste '>'.
HAHA, stakkels C++
> Alternativt kan man overføre den container, hvor resultatet skal gemmes by
> reference - sådan som det vises i "Accelerated C++" på side 56, i kapitlet
> "Organizing programs and data".
Ja, men det er jo nærmere af nød end af lyst, når man koder sådan.
Koden er nu engang simplest at læse og forstå, når parametre er input og
returværdi er output. På den måde får man også større udtryksfuldhed, idet
man nemmere kan opbygge meningsfulde udtryk. Fx.
myfunc(mkTestSet());
i stedet for
std::set<MyClass, MyComparator> ugly;
mkTestSet(ugly);
myfunc(ugly);
> > Men det er også sundt lige fra starten at skelne mellem "core language"
og
> > "library".
> "Accelerated C++" beskriver det øverst på side 2.
Okay, øverst på side 2 kan man læse hvad der er core language, og hvad der
er i librariet?
Jeg er imponeret
[ memory debugging]
> > Ja - det er faktisk fine værktøjer. Det sørgelige er at der er brug for
dem.
> Det kan man sige om alle (gode) debug værktøjer generelt - f.eks. ens
> interaktive debugger og fejlmeldingerne fra compileren.
Nogle slags værktøjer er nærmest universelle, og man vil aldrig kunne
undvære dem.
Men lige netop memory debugging værktøjer klarer man sig fint uden, i næsten
alle andre programmeringssprog.
> Der er en væsentlig forskel, i denne sammenhæng, mellem .LIB og .DLL.
> .LIB filer er et intern anliggende, for en given compiler i en given
> version.
Okay, det har du forresten ret i. Det er også p*sseirriterende at Borland og
MSVC har forskellige LIB-fil formater.
På Linux er der kun .a, men det er måske fordi der kun er gcc
Mvh. Bjarke
| |
Mogens Hansen (02-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 02-08-02 06:17 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Det var ikke et citat, det var min vurdering.
Netop - en subjektiv vurdering, som ikke er funderet i det ophav du påstod.
> Men hvis du vil have en reference, så kan det vel ikke udtrykkes klarere
end
> Stroupstrup himself gør det i sin klassiske artikel,
> http://www.research.att.com/~bs/new_learning.pdf, om hvordan man bør lære
> C++, og puttet ind mellem linierne, hvorfor C++ er så "fedt".
Man kan godt vise, hvordan visse C programmeringstile er besværligere i
forhold til C++, uden at have behov for negative, unuancerede udsagn som
* C er et laverestående sprog som man godt kan undvære
* C anses for deprecated når vi har C++
[8<8<8<]
> Mit lidt mere skjulte budskab er at C++ er noget skrammel
Netop.
Det ved jeg - men hvorfor skjule det ?
[8<8<8<]
> Meget sjældent, vil jeg mene. Den optimering har kun lov til at
> bort-optimering af kopiering af det udtryk der står efter return.
Objektivt forkert.
> Så, simpelt eksempel:
> std::set<MyClass, MyComparator> mkTestSet()
> {
> std::set<MyClass, MyComparator> result;
> result.insert(someObject);
> result.insert(otherObject);
> return result;
> }
>
> Ingen optimering her.
Objektivt forkert.
[8<8<8<]
> Okay, det har du forresten ret i. Det er også p*sseirriterende at Borland
og
> MSVC har forskellige LIB-fil formater.
Det er ikke kun mellem compilerleverandører der er det problem.
Alene det simple faktum at sizeof(bool) var 4 i MSVC 5 og er 1 i MSVC 6, gør
at LIB-filer lavet med den ene ikke fuldt ud kan bruges med den anden.
Det at Standard library i MSVC.NET er væsentligt opdateret i forhold til
MSVC 6 gør formodentlig det samme.
Hvis man læser dokumentationen til MSVC.NET omkring LTCG (Link Time Code
Generation) vil man se at de siger at man ikke skal forvente at LIB filer
lavet med den nuværende er kompatible med kommende versioner.
På MS-Windows platformen har man DLL og COM, med deres respektive begrænsede
type-systemer, til rådighed for at blande binære produkter fra forskellige
compilere - uanset om det er fra forskellige leverandører eller det blot er
forskellige versioner.
> På Linux er der kun .a, men det er måske fordi der kun er gcc
På Linux er der andre compilere.
Intel C++ er ikke fuldt binær kompatibel med gcc, fordi ABI pt. ikke er
komplet.
gcc 2.95.x er ikke fuldt binær kompatibel med gcc3.0
gcc 3.2 bliver ikke fuldt binær kompatibel med gcc 3.1.x, fordi ABI pt. ikke
er komplet.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (02-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 02-08-02 22:06 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aid4aq$3sv$1@news.cybercity.dk...
> > Mit lidt mere skjulte budskab er at C++ er noget skrammel
> Netop.
> Det ved jeg - men hvorfor skjule det ?
Fordi det ikke var emnet for diskussionen, men jeg *kan* bare ikke lade være
med at benytte enhver chance for at omvende hedenske C++-brugere til
lyksalighederne i "firstclassness" og late binding (jeg *sagde* ikke
P-ordet - det er vist snart en uge siden jeg har nævt det ord i en
nyhedsgruppe!?! :)
Siden du ikke mener der er grund til at undertrykke mine uforbeholdne
meninger om C++, så kan jeg da lægge ud med at bringe et glimrende citat fra
en god internetside ( http://www.nothings.org/computer/cpp.html). Den er
første Google-hit på "C++ sucks"!
----------------
Why C++ Sucks
C++ sucks because it is a mis-designed pile of crap.
All you have to do is read Bjarne Stroustrop's book on the design and
evolution of C++ to understand why: C++ is the iMac of computing languages.
----------------
Virkelig poetisk, må man sige :)
Lidt flere morsomheder/citater fundet på nettet:
- The last good thing written in C was Franz Schubert's Symphony number 9.
- When your hammer is C++, everything begins to look like a thumb.
- Read through the ISO C++ standard document and look for occurences of the
phrases "behavior is undefined" and especially "no diagnostic is required".
- C was a good language when the PDP-11 was a good computer. It's largely
past its prime now and should be abandoned in favor of more expressive and
flexible languages. C++ and Java are actually worse, unfortunately; Common
Lisp is more suitable for general application programming, as are Python and
in some cases Smalltalk.
- As any C programmer knows, "C++" means "increment C, but use its old
value". For precisely this reason, most C++ programmers deprecate the use of
C++ for most purposes, preferring "++C", which can often avoid creation of a
temporary.
---------------------
Jeg mener at det eneste gode man kan sige om C++ er at det er "en bedre C".
Det er bare ikke godt nok til mig.
> > Meget sjældent, vil jeg mene. Den optimering har kun lov til at
> > bort-optimering af kopiering af det udtryk der står efter return.
> Objektivt forkert.
Jaja, okay, nu har jeg læst lidt på lektien... :)
Det ændrer dog ikke ved at man ofte har brug for pointere (som var det det
handlede om) til at lade objekter leve længere end de
funktioner-invokationer der skaber dem, og til fx at få polymorfi med.
Så jeg påstår stadig at man ikke kan undvære pointere ret længe i C++.
Mvh Bjarke
| |
Mogens Hansen (03-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 03-08-02 08:56 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
Jeg har ikke noget problem med at du ikke bryder dig om C++.
Det er naturligvis et forhold som Dan Christensen bør tage i betragning, når
han vurderer dine udtalelser i denne tråd.
[8<8<8<]
> Jaja, okay, nu har jeg læst lidt på lektien... :)
Godt.
[8<8<8<]
> Det ændrer dog ikke ved at man ofte har brug for pointere (som var det det
> handlede om) til at lade objekter leve længere end de
> funktioner-invokationer der skaber dem, og til fx at få polymorfi med.
Var det det som det handlede om ?
<citat>
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:QPZ19.552$m15.94451@news010.worldonline.dk...
> Man får meget hurtigt brug for pointere. Alternativet er at funktioner der
> returnerer komplekse strukturer, skal returnere fx en std::map eller
> std::list by value. Det har man ikke lyst til i ret lang tid.
</citat>
Det forekommer mig bestemt, at du talte om returnering af komplekse
strukturer, og ikke om objekt levetid eller polymorfi.
Det forkommer mig bestemt, at du igen faktuelt tager fejl og forsøger at
skifte emne.
Når jeg læser hurtigt denne tråd igennem, og tæller op hvor du objektivt har
taget fejl, så får jeg følgende liste:
1. " "Bjarne Stroustrup"-skolen" mener at C er et laverestående sprog som
man kan undvære"
2. " De ("Bjarne Stroustrup"-skolen red.) anser C som deprecated når vi
har C++"
3. At en compiler der ikke kan linke med defacto LIB filer ikke vil har
mange chancer.
4. Forkerte påstande om hvornår der må foretages "Return Value
Optimization" i C++
5. At på Linux er gcc den eneste (C++) compiler
Jeg vil ikke garantere at listen er komplet.
Dertil kommer de to mest kedelig ting:
1. Du beskylder en navngiven person (Bjarne Stroustrup), under dække af
udtrykket " "Bjarne Stroustrup" skolen", for udtalelser og holderninger, som
du simpelt hen ikke har belæg for. Det er for mig et alvorligt forhold, at
man overskrider ytringsfrihedens grænser. Det må vist nærme sig det juraen
kalder injurier.
2. Du insinuerer at det råd jeg oprindeligt gav Dan Christensen, vil
medføre at man ikke lærer om væsentlige emner i C++, såsom typer, scope,
variable etc. Igen er dine insinueringer fuldstændigt ubegrundet, idet du
ikke kender "Accelerated C++". Desuden er de fejlagtige, sådan som jeg har
påvist i denne tråd.
Hvordan syntes du selv det går ?
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (03-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 03-08-02 12:38 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aig23q$ohh$1@news.cybercity.dk...
> > Det ændrer dog ikke ved at man ofte har brug for pointere (som var det
det
> > handlede om) til at lade objekter leve længere end de
> > funktioner-invokationer der skaber dem, og til fx at få polymorfi med.
>
> Var det det som det handlede om ?
Ja.
> <citat>
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
> news:QPZ19.552$m15.94451@news010.worldonline.dk...
> > Man får meget hurtigt brug for pointere. Alternativet er at funktioner
der
> > returnerer komplekse strukturer, skal returnere fx en std::map eller
> > std::list by value. Det har man ikke lyst til i ret lang tid.
> </citat>
>
> Det forekommer mig bestemt, at du talte om returnering af komplekse
> strukturer, og ikke om objekt levetid eller polymorfi.
> Det forkommer mig bestemt, at du igen faktuelt tager fejl og forsøger at
> skifte emne.
Hvor vil du hen? Skal vi lege citatpoliti? Er det virkelig diskussionen, vi
skal diskutere, i stedet for det egentlige emne?
Jeg skærer det gerne ud i pap: I det du <citerer>, siger jeg:
1. Man får meget hurtigt brug for pointere
2. Uden pointere bliver man nødt til at returnere by value, også når
returtypen er kompleks.
3. Det (det må så være 2.) bliver man hurtigt træt af.
Pkt. 2 er faktuelt rigtig, RVO eller ej. Pkt. 1 og især pkt. 3 er
naturligvis mit subjektive skøn - det kan ikke være andet.
I det du quoter højere oppe siger jeg:
1. Man har ofte brug for pointere - det var det det handlede om.
2. Man har brug for dem til at lade objekter leve længere end
funktionsinvokationerne.
3. og til fx at få polymorfi med.
Jeg kan ikke se meget emneskift i det.
Og RVO (return value optimization) eller ej, så har man ofte behov for at
returnere en pointer i stedet for et "by value"-objekt.
Hvor længe tror *du* man kan klare sig uden pointere? Du lod til at mene at
bare man har RVO, så kan man i høj grad undvære pointere. Hvor store stykker
kode har du selv skrevet i C++ uden brug af pointere?
> Når jeg læser hurtigt denne tråd igennem, og tæller op hvor du objektivt
har
> taget fejl, så får jeg følgende liste:
Oh shit, citatpolitiet går i aktion igen...
> 1. " "Bjarne Stroustrup"-skolen" mener at C er et laverestående sprog
som
> man kan undvære"
> 2. " De ("Bjarne Stroustrup"-skolen red.) anser C som deprecated når vi
> har C++"
Åh, hr betjent, kan jeg ikke få lidt rabat her? Det her må da tælle som én
ting.
Iøvrigt er det ikke en objektiv fejltagelse. Jeg har aldrig påstået at de
har sagt det. Det kan ikke være andet end min subjektive vurdering af
holdningen hos visse C++-programmører, som jeg oplever den på internet og i
fagblade, hvilket du også selv har indset:
MH> Netop - en subjektiv vurdering, som ikke er funderet i det ophav du
påstod.
Jeg har så tilladt mig at kalde den retning for "Bjarne Stroustrup"-skolen,
da jeg mener at BS er en af de største repræsentanter for de holdninger jeg
henviser til. Jeg henviste endda til en af BS's essays, hvor jeg mener at 1.
og 2. tydeligt fremgår.
> 3. At en compiler der ikke kan linke med defacto LIB filer ikke vil har
> mange chancer.
Hvis du skal citere, må du hellere citere korrekt.
Det jeg sagde var "defacto-libfiler (.LIB og .DLL under Windows)"
Som du har korrekt påpeget, så er .LIB filer ikke altid kompatible, men jeg
holder stadig på at en compiler skal være kompatibel med
standard-kaldkonventionerne i DLL filer (for Windows' vedkommende) - det er
typisk det der kaldes "WINAPI", dvs. funktion rydder stak, og argumenter
pushes på i C-rækkefølge.
> 4. Forkerte påstande om hvornår der må foretages "Return Value
> Optimization" i C++
Hov hov, der skal ikke bruges flertal her! Det var kun én forkert påstand
;).
Sagen er at "klassisk" C++ kun tillod RVO af "unnamed objects", dvs.
temporaries i return-udtrykket. Jeg var blot ikke klar over at
ISO-standarden har liberaliseret dette og nu også tillader "named return
value optimization".
Man skal vel lære noget nyt hver dag
> 5. At på Linux er gcc den eneste (C++) compiler
Nu presser du vist også citronen for at komme op på 5. Det jeg sagde, var:
<citat>
BDE> På Linux er der kun .a, men det er måske fordi der kun er gcc
</citat>
Ligner det en objektiv påstand om at der faktuelt kun er én compiler under
Linux?
Eller ser det ud som om jeg bare henviser til at gcc praktisk talt sidder på
"markedet" for C/C++ compilere under Linux?
Skal alting formuleres i amerikansk jura-disclaimer-sprog?
> Jeg vil ikke garantere at listen er komplet.
Det er vi nok ikke mange der sover dårligt om natten over.
> Dertil kommer de to mest kedelig ting:
> 1. Du beskylder en navngiven person (Bjarne Stroustrup), under dække af
> udtrykket " "Bjarne Stroustrup" skolen", for udtalelser og holderninger,
som
> du simpelt hen ikke har belæg for.
Jeg beskylder ham ikke for nogen udtalelser, kun holdninger. Vi kan nok ikke
så godt spørge ham selv. Men hvad mener du? Tror du at BS mener at der er
grund til at bruge C til noget som helst? Hans essey, som jeg linkede til,
giver ikke ligefrem indtryk af det.
> Det er for mig et alvorligt forhold, at
> man overskrider ytringsfrihedens grænser. Det må vist nærme sig det juraen
> kalder injurier.
IANAL ;), men jeg vil mene at du tager fejl heri. Jeg må beskylde hvem jeg
vil for de holdninger jeg vil, sålænge det ikke er ærekrænkende. Jeg må fx
ikke i offentligt rum beskylde BS for at være nazist eller pædofil, men fx
gerne for at mene at C er deprecated.
> Hvordan syntes du selv det går ?
Jeg synes diskussionen gik godt, og at den trods alt var indholdsrig (fra
begge sider), indtil du begyndte at lege citatpoliti.
Mvh. Bjarke
| |
Mogens Hansen (03-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 03-08-02 22:25 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Sagen er at "klassisk" C++ kun tillod RVO af "unnamed objects", dvs.
> temporaries i return-udtrykket.
Forkert igen igen - sådan er sagen _ikke_.
Prøv at læse
Inside the C++ Object Model
Stanley B. Lippman
ISBN 0-201-83454-5
fra 1996, side 55-59.
Afsnittet handler om "Named Return Value" (NRV) optimering.
Bemærk at Stanley B. Lippman spillede en væsentlig rolle i implementeringen
af cfront - den oprindelige C++ frontend, som blev lavet i gruppen under
Bjarne Stroustrups ledelse. Beskrivelserne i bogen stammer i høj grad fra
dette arbejde.
Eller kig i
The Annotated C++ Reference Manual
Margaret A. Ellis, Bjarne Stroustrup
ISBN 0-201-51459-1
fra 1992, side 300-303, kapitel 12.1.1c
De 2 kilder må vist ligge inden for den gængse opfattelse af hvad "klassisk
C++" er.
Hvorfra har du egentlig alle dine opfattelser af hvad C++ er og ikke er ?
Jeg er ved at være ret imponeret over hvor mange skråsikre udtalelser (som
"Sagen er ...") du er kommet med i denne tråd, samtidig med at de er
_fuldstændigt_ ufunderet og objektivt forkerte.
Tænk at du endnu ikke har lært at du skal gøre dit hjemmearbejde ordentligt.
> Jeg var blot ikke klar over at
> ISO-standarden har liberaliseret dette og nu også tillader "named return
> value optimization".
Det er en historisk forkert fremstilling.
Som forklaret ovenfor - sådan hænger det ikke sammen.
> Man skal vel lære noget nyt hver dag
Tilsyneladende.
[8<8<8<]
> Nu presser du vist også citronen for at komme op på 5. Det jeg sagde, var:
> <citat>
> BDE> På Linux er der kun .a, men det er måske fordi der kun er gcc
> </citat>
>
> Ligner det en objektiv påstand om at der faktuelt kun er én compiler under
> Linux?
Ja.
Som jeg forstår dansk, betyder "fordi der kun er gcc" at der kun findes den
ene.
> Eller ser det ud som om jeg bare henviser til at gcc praktisk talt sidder
på
> "markedet" for C/C++ compilere under Linux?
Nej, ikke som jeg læser dansk.
I så fald kunne du f.eks. have sagt at gcc er den altdominerende compiler på
Linux.
[8<8<8<]
> Jeg beskylder ham ikke for nogen udtalelser, kun holdninger. Vi kan nok
ikke
> så godt spørge ham selv.
Hvorfor ikke, hvis du virkelig mener at du har en _rigtig_ god grund til at
forstyrre ham ( http://www.research.att.com/~bs/bs_faq.html#ask) - husk den
kære mand får mange mails.
..
Husk iøvrigt på at det ikke er usandsynligt at Bjarne Strousturp, blandt
mange andre, faktisk læser denne tråd - inclusive dine udtalelser som
<citat>
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:kyi29.1101$m15.257255@news010.worldonline.dk...
> Man skal ikke lytte til Stroustrup . Han er en bitter gammel mand der
er
> sur på Java og Microsoft
</citat>
> Men hvad mener du? Tror du at BS mener at der er
> grund til at bruge C til noget som helst?
Jeg _tror_ så afgjort at han foretrækker at bruge C++ frem for C. Eller
havde han nok ikke designet C++ - alt andet er som at forestille sig
statsminister Anders Fogh Rasmussen stemme på SF ved næste folketingsvalg.
Det fjerner ikke behovet for sommetider at skrive relativ lavniveau kode i
en stil der svarer til eller er identisk med hvad man ville gøre i C (se
f.eks.
http://www.cuj.com/articles/2002/0208/0208c/0208c.htm?topic=reference, som
jeg tidligere i tråden har henvist til).
Det betyder _ikke_ at jeg _overhovedet_ kan forestille mig at han har behov
for udtalelser som:
* "C er et laverestående sprog som man godt kan undvære"
* "C som deprecated når vi har C++"
Som jeg kender Bjarne Stroustrup, udtrykker han sig ikke på den måde
nedladende og generaliserende.
Sådan er hans personlighed simpelthen ikke.
Det typiske er at han fortæller hvordan han syntes man kan gøre noget bedre.
Der er en væsenlig forskel.
Prøv dog at _læse_
http://www.cuj.com/articles/2002/0207/0207d/0207d.htm?topic=reference
http://www.cuj.com/articles/2002/0208/0208c/0208c.htm?topic=reference
hvis du oprigtigt er interesseret i hvad Bjarne Stroustrup mener om
forholdet mellem C og C++.
Der er ikke nogen grund til at gætte.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (04-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 04-08-02 01:07 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aihhcg$2la5$1@news.cybercity.dk...
> > Sagen er at "klassisk" C++ kun tillod RVO af "unnamed objects", dvs.
> > temporaries i return-udtrykket.
> Forkert igen igen - sådan er sagen _ikke_.
Jamen, kære Mogens, hvis det ligger dig så meget på sinde at gruppen kan
nyde en præcis gennemgang af hvad det *egentlig* er med den der
RVO-optimering, så kunne du jo skrive en lille artikel om emnet og poste
her, i stedet for denne arrogante dom og henvisen til ISBN-numre.
Iøvrigt er det svært at få andet indtryk end det jeg fik, når man læser
følgende:
Scott Meyers: "In July 1996, the standardization committee decided that
named objects may be treated essentially the same as unnamed objects for
purposes of performing the return value optimization."
> Hvorfra har du egentlig alle dine opfattelser af hvad C++ er og ikke er ?
Det kommer til mig som guddommelige åbenbaringer.
> > Ligner det en objektiv påstand om at der faktuelt kun er én compiler
under
> > Linux?
>
> Ja.
Nå. Men så kan jeg blot sige at du må have forstået det på en anden måde end
det var ment - måske forsøger du også ligefrem at misforstå hvad der kan
misforstås. Eller noget. Jeg fatter i hvert fald ikke hvorfor det er vigtigt
for dig at blive ved at kværulere over citater du finder længere tilbage i
tråden. Selv når jeg fortæller dig hvad jeg mente (ifald du ikke kunne
begribe det) og enhver misforståelse derfor burde være ryddet af vejen, så
skal du lige have gjort gældende at det ud fra et juridisk
kværulantsynspunkt ikke var det der stod. Er det sjovt? Bliver Usenet et
federe sted på den måde?
> Som jeg forstår dansk, betyder "fordi der kun er gcc" at der kun findes
den
> ene.
Så prøv at lære at forstå dansk på et mere uformelt og afslappet plan.
> Nej, ikke som jeg læser dansk.
> I så fald kunne du f.eks. have sagt at gcc er den altdominerende compiler
på
> Linux.
Ja, men det gad jeg ikke, for det burde være indlysende for enhver
Jeg kom bare med en halv-vittig, halv-ligegyldig, men i praksis sandfærdig
kommentar om at de netop nævnte LIB-inkompatibiliteter er irrelevante under
Linux fordi der alligevel kun er én compiler. Du kommer så med en ligeså
ligegyldig oplysning om at der skam *findes* andre compilere til Linux (som
om vi ikke ved det).
> Hvorfor ikke, hvis du virkelig mener at du har en _rigtig_ god grund til
at
> forstyrre ham
Det mener jeg overhovedet ikke.
Men du virker oprigtigt interesseret i at få denne sag belyst til bunds, så
jeg vil foreslå at du tager kontakt.
> Husk iøvrigt på at det ikke er usandsynligt at Bjarne Strousturp, blandt
> mange andre, faktisk læser denne tråd - inclusive dine udtalelser som
> <citat>
> > Man skal ikke lytte til Stroustrup . Han er en bitter gammel mand der
> > er sur på Java og Microsoft
> </citat>
Tror du BS er så sart? Skulle jeg sige noget andet når BS lytter med end når
han ikke gør? Det kaldes bagtalelse.
Jeg står gerne ved mine udtalelser, navnligt når man husker at citere " "
.
Han er iøvrigt, som alle andre, velkommen til at deltage.
> Det betyder _ikke_ at jeg _overhovedet_ kan forestille mig at han har
behov
> for udtalelser som:
> * "C er et laverestående sprog som man godt kan undvære"
> * "C som deprecated når vi har C++"
Jeg har ikke talt om at udtale ovenstående sætninger. Jeg har kun påstået af
nogen *mener* sådan. Selvfølgelig kan jeg ikke *vide* hvad de mener, men jeg
kan jo komme med et godt gæt, som endda underbygges af dine egne
henvisninger til bl.a. CUJ artiklen.
Hvorfor er det egentlig så vigtigt for dig at vedblive at gentage disse to
sætninger? Føler du at du her har fat i noget vigtigt som altså lige skal
undersøges helt til bunds? Forventer du at jeg skal bryde grædende sammen og
indrømme at jeg ikke kan vide *med* *sikkerhed* at nogen tænker sådan? Kan
du så sove mere roligt, eller hvordan?
Her er nogle udpluk fra dine seneste mails - meget varieret, må man sige.
------------------------
[31.07.2002 22:57]
> Hvorfra har du at " "Bjarne Stroustrup"-skolen mener at C er et
> laverestående sprog som man godt kan undvære" ?
[01.08.2002 17:45]
> Hvor, i det miljø du kalder "Bjarne Stroustrup-skolen", har du udsagnet
"De
> anser C som deprecated når vi har C++" fra ?
[...]
> Der står så vidt jeg kan se ikke noget med:
> * at C er et laverestående sprog som man godt kan undvære
> * at C anses for deprecated når vi har C++
[02.08.2002 07:16]
> Man kan godt vise, hvordan visse C programmeringstile er besværligere i
> forhold til C++, uden at have behov for negative, unuancerede udsagn som
> * C er et laverestående sprog som man godt kan undvære
> * C anses for deprecated når vi har C++
[03.08.2002 09:56]
> Når jeg læser hurtigt denne tråd igennem, og tæller op hvor du objektivt
har
> taget fejl, så får jeg følgende liste:
> 1. " "Bjarne Stroustrup"-skolen" mener at C er et laverestående sprog
som
> man kan undvære"
> 2. " De ("Bjarne Stroustrup"-skolen red.) anser C som deprecated når vi
> har C++"
[03.08.2002 23:25 - den du lige nåede at tilføje til listen]
> Det betyder _ikke_ at jeg _overhovedet_ kan forestille mig at han har
behov
> for udtalelser som:
> * "C er et laverestående sprog som man godt kan undvære"
> * "C som deprecated når vi har C++"
[skal vi også lige have en 04.08.2002?]
------------------------
> Sådan er hans personlighed simpelthen ikke.
Der står da ikke noget i hans FAQ om at hans personlighed ikke er sådan.
Hvor har du det fra? Du må da kunne henvise til en kilde, hvor der står at
"sådan er hans [Bjarne Stroustrups, red.] personlighed [...] ikke."
> Prøv dog at _læse_
> http://www.cuj.com/articles/2002/0207/0207d/0207d.htm?topic=reference
> http://www.cuj.com/articles/2002/0208/0208c/0208c.htm?topic=reference
> hvis du oprigtigt er interesseret i hvad Bjarne Stroustrup mener om
> forholdet mellem C og C++.
Det interesserer mig ærlig talt ikke så meget som det tilsyneladende
interesserer dig.
Han giver udtryk for at man hellere skal skrive i C-style i C++ end at bruge
C direkte. De fleste af hans "Ten red herrings" ser således ud til at handle
om at overbevise skeptikeren om at C++ sagtens kan erstatte C (bl.a. fordi
C++ specielt omfatter det meste af C).
Bjarke
| |
Mogens Hansen (04-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 04-08-02 10:43 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:wm_29.2696$G3.233036@news010.worldonline.dk...
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
> news:aihhcg$2la5$1@news.cybercity.dk...
>
> > > Sagen er at "klassisk" C++ kun tillod RVO af "unnamed objects", dvs.
> > > temporaries i return-udtrykket.
> > Forkert igen igen - sådan er sagen _ikke_.
>
> Jamen, kære Mogens, hvis det ligger dig så meget på sinde at gruppen kan
> nyde en præcis gennemgang af hvad det *egentlig* er med den der
> RVO-optimering, så kunne du jo skrive en lille artikel om emnet og poste
> her, i stedet for denne arrogante dom og henvisen til ISBN-numre.
Det ligger mig på sinde at korrigere de fejlopfattelser du kommer med i
denne tråd.
Det er ikke en arrogant dom - det er en præcis præsentation af fakta.
Fakta burde kunne afslutte diskutionen.
Hvis du har andre præcise kilder til hvornår og hvordan RVO blev designet,
så kom med dem.
Eftersom hverken du, jeg eller Scott Meyers var med til at designe RVO, kan
vi ikke komme med førstehånds vidneudsagn.
Vi er henvist til at komme med andenhånds udtalelser, som at referere til
Bjarne Stroustrup og Stanley B. Lippman eller at komme med trediehånds
udtalelser, som at referere til Scott Meyers.
> Iøvrigt er det svært at få andet indtryk end det jeg fik, når man læser
> følgende:
> Scott Meyers: "In July 1996, the standardization committee decided that
> named objects may be treated essentially the same as unnamed objects for
> purposes of performing the return value optimization."
Scott Meyers, som normalt er en god og pålideligt kilde, havde galt fat i
hvad der var gældende omkring den optimering.
Jeg husker Stanley B. Lippman's anmeldelse i "C++ Report" af een af Scott
Meyers iøvrigt glimrende bøger, hvor Scott Meyers skrev forkert om RVO. Stan
netop påpegede det særligt alvorlige i netop Scott Meyers var upræcis.
Hvis du læser Scott Meyers citatet igen, står der ikke noget om at reglen
blev ændret - blot at den blev vedtaget. Jeg har ikke grund til at tro, at
det er forkert hvad du citerede Scott Meyers for.
"The Annotated C++ Reference Manual", fra 1992 som jeg henviste til var
basisdokumentet for standardiseringsarbejdet af C++.
Bogen nævner begge former for optimering.
[8<8<8<]
> Bliver Usenet et
> federe sted på den måde?
Bliver Usenet et federe sted af at præsentere en læng række ufunderede og
ofte direkte forkerte usagn som om det er fakta ?
Usenet bliver et federe sted, hvis man som f.eks. Dan Christensen kan stille
et godt og relevant spørgsmål og få et sagligt og brugbart svar.
Hvis du f.eks. havde sagt at du mente at Dan Christensen ville få mere glæde
af at lære Python, så er det fint nok med mig. Det kan være din holdning, og
den har jeg meget respekt for - sikkert mere end du sikkert tror.
Men du må nødvendigvis være parat til at stå til ansvar for de udtalelser du
kommer med.
[8<8<8<]
> Så prøv at lære at forstå dansk på et mere uformelt og afslappet plan.
Du må acceptere at Usenet er et skriftligt medie, hvor man kun kan læse det
der bliver skrevet, og ikke se om forfatteren har et sarkastisk eller
ironisk smil om munden da det blev skrevet.
[8<8<8<]
> Jeg kom bare med en halv-vittig, halv-ligegyldig, men i praksis sandfærdig
> kommentar om at de netop nævnte LIB-inkompatibiliteter er irrelevante
under
> Linux fordi der alligevel kun er én compiler. Du kommer så med en ligeså
> ligegyldig oplysning om at der skam *findes* andre compilere til Linux
(som
> om vi ikke ved det).
Det er dine ligegyldige og upræcise kommentarer jeg opponerer imod.
De afsporer en reel formidling af _viden_.
[8<8<8<]
> > Hvorfor ikke, hvis du virkelig mener at du har en _rigtig_ god grund til
> at
> > forstyrre ham
>
> Det mener jeg overhovedet ikke.
> Men du virker oprigtigt interesseret i at få denne sag belyst til bunds,
så
> jeg vil foreslå at du tager kontakt.
Du skifter emne igen.
Jeg svarede på dit udsagn om at "Vi kan nok ikke så godt spørge ham selv.".
Det var igen et af dine udsagn der faktuelt ikke er særligt præcise og
velfunderede.
Man _kan_ spørge Bjarne Stroustrup, ifølge hans FAQ. Bjarne Stroustrup
e-mail adresse er offentligt kendt. Men jeg vil ikke opfordre nogen til at
forestyrre den kære mand i tide og utide.
> Jeg har ikke talt om at udtale ovenstående sætninger. Jeg har kun påstået
af
> nogen *mener* sådan.
Du fusker med citaterne.
Det var ikke "nogen" du påstod havde den holdning - du påstod at " "Bjarne
Stroustrup"-skolen" havde den holdning.
Der er _væsenlig_ forskel.
Der er naturligvis "nogen" der har den holdning - der er "nogen" der har
næsten en hvilken som helst holdning.
>Selvfølgelig kan jeg ikke *vide* hvad de mener, men
jeg
> kan jo komme med et godt gæt, som endda underbygges af dine egne
> henvisninger til bl.a. CUJ artiklen.
Selvfølgelig kan kan man _vide_ noget om hvad f.eks. Bjarne Stroustrup mener
om visse ting - man kan læse hvad han har sagt han mener om tingene.
Man kan f.eks. _vide_ hvad han vil svare på Dan Christensens oprindelige
spørgsmål.
Man kan blot ikke tillade sig at ekstrapolere holdninger, der ikke er belæg
for, hvis man vil optræde seriøst og troværdigt.
[8<8<8<]
> > Sådan er hans personlighed simpelthen ikke.
>
> Der står da ikke noget i hans FAQ om at hans personlighed ikke er sådan.
> Hvor har du det fra?
Det var et førstehåndsvidende udsagn om at sådan er hans personlighed ikke.
Kilden er entydig undertegnede.
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (03-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 03-08-02 22:51 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Pkt. 2 er faktuelt rigtig, RVO eller ej.
Kan du så ikke lige forklare os alle, hvorfor man ikke ret længe har lyst
til at returnere et std::map eller std::list by value ?
Hvis det er et performanceproblem, stammende fra oprettelse og nedlæggelse
af et temporært objekt, så er det altafgørende om der er RVO eller ej.
[8<8<8<]
> Og RVO (return value optimization) eller ej, så har man ofte behov for at
> returnere en pointer i stedet for et "by value"-objekt.
Ja da.
Men ikke blot fordi der er tale om et komplekst objekt.
Det kan være fordi objektets identitet er vigtig (f.eks. det er et bestemt
faktura-objekt, og ikke en hvilken som helst faktura-objekt lydende på samme
beløb).
> Hvor længe tror *du* man kan klare sig uden pointere? Du lod til at mene
at
> bare man har RVO, så kan man i høj grad undvære pointere.
Hvorfra har du den opfattelse ? (gerne et citat)
Det var din påstand om at man ikke ret længe har lyst til at returnere
komplekse objekter by value jeg oponerede imod. Ikke behovet for pointere
generelt.
> Hvor store stykker
> kode har du selv skrevet i C++ uden brug af pointere?
Hvor i denne tråd har jeg sagt eller antydet at man ikke har brug for
pointere i C++ ?
Jeg anbefalede Dan Christensen "Accelerated C++", som bruger en god del af
kapitel 10 "Managing memory and low-level data structures" på pointere.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (04-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 04-08-02 01:55 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aihisi$2n30$1@news.cybercity.dk...
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> > Pkt. 2 er faktuelt rigtig, RVO eller ej.
>
> Kan du så ikke lige forklare os alle, hvorfor man ikke ret længe har lyst
> til at returnere et std::map eller std::list by value ?
Pkt. 2 var "Uden pointere bliver man nødt til at returnere by value",
hvilket jo indlysende er sandt.
(forudsat at vi ikke lige orker at starte en kværulering om referencer, som
stort set er det samme i denne forbindelse).
Hvornår man ikke har lyst til at returnere en std::map eller std::list by
value... tja, der er mange muligheder... Fx. når dette std::map eller
std::list objekt findes i forvejen (dvs. før kaldet), så bør det tage
konstant tid at returnere det.
> Hvis det er et performanceproblem, stammende fra oprettelse og nedlæggelse
> af et temporært objekt, så er det altafgørende om der er RVO eller ej.
Det er nu ofte ikke så meget oprettelse/nedlæggelse, men snarere
kopieringen, der bliver dyr. Og ja, det er klart at RVO er et fremskridt
m.h.t. at undgå denne kopiering.
> > Hvor længe tror *du* man kan klare sig uden pointere? Du lod til at mene
> > at
> > bare man har RVO, så kan man i høj grad undvære pointere.
> Hvorfra har du den opfattelse ? (gerne et citat)
Ja, du ynder jo citater . Her er et:
> > Man får meget hurtigt brug for pointere. Alternativet er at funktioner
der
> > returnerer komplekse strukturer, skal returnere fx en std::map eller
> > std::list by value. Det har man ikke lyst til i ret lang tid.
> Hvorfor har man ikke lyst til det ?
> Ofte vil "return value optimization" sikre, at der ikke bliver lavet de
> ekstra kopier af objekter som man frygter.
Okayokay, det fremgår ikke som jeg huskede det - du skriver "ofte" og jeg
påstod "i høj grad".
Men det er jo ikke altid lokale objekter man returnerer, og når det ikke er
det, går RVO fløjten.
Og ja, selvfølgelig ved du godt at man har brug for pointere.
> Det var din påstand om at man ikke ret længe har lyst til at returnere
> komplekse objekter by value jeg oponerede imod. Ikke behovet for pointere
> generelt.
Okay.
Bjarke
| |
Mogens Hansen (04-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 04-08-02 10:45 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote
> > "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> > > Pkt. 2 er faktuelt rigtig, RVO eller ej.
> >
> > Kan du så ikke lige forklare os alle, hvorfor man ikke ret længe har
lyst
> > til at returnere et std::map eller std::list by value ?
>
> Pkt. 2 var "Uden pointere bliver man nødt til at returnere by value",
> hvilket jo indlysende er sandt.
> (forudsat at vi ikke lige orker at starte en kværulering om referencer,
som
> stort set er det samme i denne forbindelse).
>
> Hvornår man ikke har lyst til at returnere en std::map eller std::list by
> value... tja, der er mange muligheder... Fx. når dette std::map eller
> std::list objekt findes i forvejen (dvs. før kaldet), så bør det tage
> konstant tid at returnere det.
Ja naturligvis. Det samme gælder for ikke komplekste objekter som f.eks. et
dato objekt.
Men kan du ikke godt forklare hvorfor man ikke ret længe har lyst til at
returne kompleks objekter by value.
Altså problemerne som du ser specifikt i sammenhængen:
* komplekse objekter
* return by value
og hvorfor du ikke mener at problem ikke er påvirket af hvorvidt der er RVO
eller ej.
Spørgsmålet er _ikke_ hvorfor man ikke _altid_ vil returnere by value, og
_aldrig_ har brug for andet.
> > Hvis det er et performanceproblem, stammende fra oprettelse og
nedlæggelse
> > af et temporært objekt, så er det altafgørende om der er RVO eller ej.
>
> Det er nu ofte ikke så meget oprettelse/nedlæggelse, men snarere
> kopieringen, der bliver dyr. Og ja, det er klart at RVO er et fremskridt
> m.h.t. at undgå denne kopiering.
Blot for at være sikre på at vi er enige:
Oprettelsen af objekter returneret by value (i tilfælde af at det temporære
objekt ikke bliver elimineret) sker med copy-constructoren.
RVO fjerner oprettelsen (og dermed kopieringen) og nedlæggelsen
fuldstændigt.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (05-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 05-08-02 00:39 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aiisqa$1g50$3@news.cybercity.dk...
> Men kan du ikke godt forklare hvorfor man ikke ret længe har lyst til at
> returne kompleks objekter by value.
>
> Altså problemerne som du ser specifikt i sammenhængen:
> * komplekse objekter
> * return by value
> og hvorfor du ikke mener at problem ikke er påvirket af hvorvidt der er
RVO
> eller ej.
Jeg siger slet ikke at man aldrig har gavn af RVO.
Så lad mig nøjes med at give et eksempel på problematikken i at returnere et
komplekst objekt by value:
class Foo
{
MyComplexObject obj;
public:
MyComplexObject getObj() const { return obj; }
};
Her er den åbenlyse optimering jo "const MyComplexObject& getObj() ...".
> Blot for at være sikre på at vi er enige:
> Oprettelsen af objekter returneret by value (i tilfælde af at det
temporære
> objekt ikke bliver elimineret) sker med copy-constructoren.
> RVO fjerner oprettelsen (og dermed kopieringen) og nedlæggelsen
> fuldstændigt.
Måske er vi enige, men jeg kan godt komme til at læse din sidste sætning som
at man sparer (1) construction, (2) copy construction, (3) destruction. Jeg
vil mene at det kun er (2) og (3) man sparer.
Jeg tror egentlig at vi begge ved hvad RVO består i (om ikke hvornår den er
tilladt), men jeg prøver lige at pensle det endnu mere ud
Eksempelkode:
A f()
{
A a(1,2,3);
return a;
}
Kald: A aa = f();
Uden RVO får vi:
(1) constructor A::A(int, int, int) kaldt for 'a' objektet.
(2) copy constructor A::A(const A&) kaldt, for at kopiere 'a' ind i det der
hedder 'aa' hos kalderen.
(3) destructor A: A kaldt på 'a'.
Måske er der egentlig allerede anvendt en anden optimering her, nemlig den
der sørger for at vi ikke har en temporær værdi, f(), på kaldstedet, som
skal copy-constructes ind i 'aa', men derimod return-konstruerer direkte ind
i 'aa'. Det skal jeg ikke lige kunne sige. Virker det egentlig ikke lidt
skummelt? Har "A aa = f()" lov til at sørge for at f() hælder direkte ned i
'aa', i stedet for at konstruere en temporary med værdien "f()"? For det er
jo noget andet med "B bb = f()", her skal kaldes en B constructor, som f()
ikke har noget med at gøre, så her må jo under alle omstændigheder blive
oprettet en temporary på kaldstedet.
Hmm... skummelt - jeg må prøve at se på noget assembler-output og se hvad
populære compilere gør.
Med RVO får vi:
(1) constructor A::A(int, int, int) kaldt på 'aa' objektet!
Så man sparer en kopiering og destruktion. Der spares ikke nogen oprettelse
(A::A(1,2,3) skal nødvendigvis kaldes netop én gang).
Mvh. Bjarke
| |
Thomas Krog (04-08-2002)
| Kommentar Fra : Thomas Krog |
Dato : 04-08-02 02:47 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aihisi$2n30$1@news.cybercity.dk...
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
>
> [8<8<8<]
> > Pkt. 2 er faktuelt rigtig, RVO eller ej.
>
> Kan du så ikke lige forklare os alle, hvorfor man ikke ret længe har lyst
> til at returnere et std::map eller std::list by value ?
Fordi kørselstiden kan blive markant forøget hvis den RVO ikke bliver
gennemført. (det er ikke nær så fatalt hvis det sker for et ikke komplekst
objekt)
Nu kender jeg ikke så meget til RVO men jeg går ud fra at denne RVO normalt
bliver foretaget _inden_ der linkes. Dvs. hvis man fx. har en fil test.cpp:
struct A{
....
A& operator=(const A& a); // implementeringen befinder sig i en anden
cpp-fil
};
std::list<A> foo(){
std::list<A> res;
....
return res;
}
så kan oversætteren ikke gennemføre RVO ved funktionen foo fordi
implementeringen af A: erator= ikke befinder sig i test.cpp og derfor kan
oversætteren ikke vide om A: erator= har sidevirkninger.
En anden mulighed er at der er en "fejl" i oversætteren så den ikke opdager
alle de RVO muligheder der reelt er.
Den slags manglende RVO kan være svær at finde (gennem fejlfinding) og jeg
vil derfor sjældent turde stole på RVO (især for komplekse typer som tager
lang tid at kopiere).
| |
Mogens Hansen (04-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 04-08-02 10:45 |
|
"Thomas Krog" <rick@kampsax.dtu.dk> wrote
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote
> > "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> >
> > [8<8<8<]
> > > Pkt. 2 er faktuelt rigtig, RVO eller ej.
> >
> > Kan du så ikke lige forklare os alle, hvorfor man ikke ret længe har
lyst
> > til at returnere et std::map eller std::list by value ?
>
> Fordi kørselstiden kan blive markant forøget hvis den RVO ikke bliver
> gennemført. (det er ikke nær så fatalt hvis det sker for et ikke komplekst
> objekt)
Netop.
Derfor er det altafgørende om der compileren kan foretage optimeringen, hvis
funktionskaldet udgør en potentiel performance flaskehals.
[8<8<8<]
> så kan oversætteren ikke gennemføre RVO ved funktionen foo fordi
> implementeringen af A: erator= ikke befinder sig i test.cpp og derfor
kan
> oversætteren ikke vide om A: erator= har sidevirkninger.
Jeg tror nu ikke at det spiller nogen rolle om der er copy-assignment
operator eller ej. Det kan jeg i hvert fald ikke huske at have oplevet.
Nogle compilere laver ikke RVO, hvis der ikke er en copy-constructor. Det
har jeg oplevet. Men det er langt fra alle, og det er ikke noget formelt
krav at der skal være en copy-constructor.
Optimeringen må gerne ske, selvom copy-constructoren har sidevirkninger.
> En anden mulighed er at der er en "fejl" i oversætteren så den ikke
opdager
> alle de RVO muligheder der reelt er.
RVO er en optimering, som er _tilladt_ for at compiler - ikke tvunget, men
dog forventet.
Alle compilere jeg har undersøgt er i stand til at foretage optimeringen,
men de har lidt forskellige grænser for hvornår de opgiver at lave
optimeringen. Min erfaring er at jo bedre en compiler generelt er til at
generere high performance kode, des sværre er det at få den til at holde op
med at lave RVO.
Noget tilsvarende ser man med inline - men det er en anden historie.
> Den slags manglende RVO kan være svær at finde (gennem fejlfinding) og jeg
> vil derfor sjældent turde stole på RVO (især for komplekse typer som tager
> lang tid at kopiere).
I den situation er det en god ting at kende sin compilere grundig, så man
har en idee om hvad man kan forvente.
En profiler vil simpelt kunne måle om der er et performance problem.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 23:30 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aiisq4$1g50$2@news.cybercity.dk...
[RVO]
> Jeg tror nu ikke at det spiller nogen rolle om der er copy-assignment
> operator eller ej. Det kan jeg i hvert fald ikke huske at have oplevet.
> Nogle compilere laver ikke RVO, hvis der ikke er en copy-constructor. Det
> har jeg oplevet. Men det er langt fra alle, og det er ikke noget formelt
> krav at der skal være en copy-constructor.
Hvis der ikke er nogen copy-constructor, så er det jo lidt svært at
returnere by value.
Så er der ingenting at optimere (RVO drejer sig jo netop om at tillade
eliminering af kald til copy-constructoren, selvom copy-constructoren
potentielt kan have sideeffekter).
> har en idee om hvad man kan forvente.
> En profiler vil simpelt kunne måle om der er et performance problem.
Bortset fra at mange profilere har det bedst med en ikke-optimeret
debugudgave af koden for at kunne mappe kodestykker præcist til linienumre i
koden.
Og i ikke-optimeret kode, er RVO måske ikke foretaget
Men det er jo et generelt problem, som det er svært at gøre noget ved. Man
kan heller ikke debugge nondebug-kode, og det hænder jo at man ser noget
kode der kun fejler i Release-udgave!
Bjarke
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 05:21 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Hvis der ikke er nogen copy-constructor, så er det jo lidt svært at
> returnere by value.
Ok jeg var upræcis.
Jeg mente en copy-constructor man selv har skrevet - ikke default
copy-constructor.
[8<8<8<]
> Bortset fra at mange profilere har det bedst med en ikke-optimeret
> debugudgave af koden for at kunne mappe kodestykker præcist til linienumre
i
> koden.
Det kræver lidt mere arbejde at fortolke det, men de viser stadig nogenlunde
hvor problemet er.
[8<8<8<]
> Men det er jo et generelt problem, som det er svært at gøre noget ved. Man
> kan heller ikke debugge nondebug-kode, og det hænder jo at man ser noget
> kode der kun fejler i Release-udgave!
Vrøvl
Man kan da bare bede compileren og linker om at generere debug-information,
selv om det er optimeret kode.
Mange compilere lægger debug-informationen i separate filer, så det
eksekverbare produkt er uændret.
Venlig hilsen
Mogens Hansen
| |
Jonas Meyer Rasmusse~ (03-08-2002)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 03-08-02 00:14 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:kyi29.1101$m15.257255@news010.worldonline.dk...
[snip]
> Det jeg kalder Stroustrup-skolen, er dem der bruger C++ fordi de er
> overbeviste om at det er det bedste sprog til de fleste opgaver, og at C++
> har en stor fremtid. De er specielt begejstrede for templates og alt hvad
de
> indebærer. Når de støder på et af de mange problemer, bagateliserer de det
> med at det ikke er C++'s skyld, eller at det problem kender de godt, og
kan
> også give en god forklaring på hvorfor C++ har det problem, og det skal
nok
> blive løst i næste standard eller næste igen, eller også findes der
allerede
> et eller andet work-around der kan klare det.
>
> Uden at kende dig ret godt, og ikke for at putte folk i kasser, men jeg
vil
> skyde på at du tilhører den gruppe ;).
Du putter jo netop folk i kasser! Det samme gælder, når du i dit korstog for
at hive folk
væk fra C++, antager at den generelle læser af denne gruppe ikke er
kompetent nok
til at foretage valg af sprog - ja, du skriver endda at begejstrede C++
brugere ville skifte hvis
de så på et andet sprog.
Du er naiv, hvis du tror at alle C++ brugere ikke har overvejet deres valg,
og aldrig har programmeret i andet end C++.
C++ er ganske som du siger det, et sprog med suveræn performance, og det vil
som regel være
en væsentlig faktor for de personer som vælger det - det er ikke alle der
har det privilegie at
kunne nøjes med at kode kører 10 gange langsommere fordi den skal fortolkes.
Udover ydelsen,
så kommer der faktisk de fordele som du klippede ud fra BS' faq - vel og
mærke hvis man sammenligner
med sprog som har samme ydelse som C++(det vil så formentlig hovedsagligt
være C).
Og Ja, du har ret, der er nogen pitfalls i C++, og det kan være svært, men
det er stadig det bedste
valg, hvis man vægter performance højt, og vi har valgt at leve med dem, da
der ikke er noget
bedre alternativ lige for tiden.
Og så syntes jeg ærligt talt du har givet fint udtryk for dine fine
fornemmelser mht C++,
i tråde hvor det har været rimeligt irrelevant, og vil foreslå dig
at starte et tråd, hvis du har noget du gerne vil diskutere.
mvh Jonas
| |
Bjarke Dahl Ebert (03-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 03-08-02 01:37 |
|
"Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> wrote in message
news:aif3o9$ng6$1@eising.k-net.dk...
> Du putter jo netop folk i kasser! Det samme gælder, når du i dit korstog
for
> at hive folk
> væk fra C++, antager at den generelle læser af denne gruppe ikke er
> kompetent nok
> til at foretage valg af sprog
Der er jo ingen "generel læser" af denne gruppe. Nogle af meget
velbevandrede i C++, mens andre knapt kan skrive en Hello, World! Intet
indlæg kan ramme alles interesse, og jeg er da ked af hvis jeg har skudt
under dit mål med ting der er trivialiteter for dig.
Jeg forsøger iøvrigt ikke at vælge sprog for nogen, jeg kommer blot med mine
syn på visse uheldige aspekter af bl.a. C++. Disse ting er måske
ligegyldigheder for dem som godt kender alle problemerne og af en eller
anden grund (fx performancekrav) vælger at leve med dem. For andre kan det
måske være godt nok at få lidt "second opinion" på forskellige anbefalinger.
Skulle dette ikke være tilfældet, undskylder jeg at have spildt folks tid.
> - ja, du skriver endda at begejstrede C++
> brugere ville skifte hvis
> de så på et andet sprog.
Jaja, må der være plads til lidt sarkasme og "language pissing contest"? ;)
> Du er naiv, hvis du tror at alle C++ brugere ikke har overvejet deres
valg,
> og aldrig har programmeret i andet end C++.
Der er da mange grunde til at folk bruger C++.
Nogle har et godt kendskab til flere forskellige slags programmeringssprog
og vælger C++ til de opgaver hvor det er et godt valg.
Men jeg ved da at mange programmerer i C og C++, simpelthen fordi de ikke
*kender* noget potentielt alternativ - ikke fordi de har valgt C eller C++
blandt mange muligheder. Man kan vel altid slå lidt på tromme for at udvide
ens horisont.
> C++ er ganske som du siger det, et sprog med suveræn performance, og det
vil
> som regel være
> en væsentlig faktor for de personer som vælger det - det er ikke alle der
> har det privilegie at
> kunne nøjes med at kode kører 10 gange langsommere fordi den skal
fortolkes.
Det er da klart at mange C++-programmører bruger det fordi performance skal
være optimal.
Men der skrives sjovt nok også masser af software i C++, hvor
runtime-performance er uden reel betydning.
> Udover ydelsen,
> så kommer der faktisk de fordele som du klippede ud fra BS' faq - vel og
Jeg klippede dem netop ud for at prøve at argumentere for at det ikke var
fordele. Det er selvfølgelig rigtigt at C++ er mere udtryksfuldt end C, men
de andre såkaldte fordele mener jeg BS griber ud af luften.
> Og Ja, du har ret, der er nogen pitfalls i C++, og det kan være svært, men
> det er stadig det bedste valg, hvis man vægter performance højt,
Tja, C og C++ ligger i hvert fald *blandt* de gode valg, hvis performance er
et knald-eller-fald kriterie. Der er andre programmeringssprog der kommer
tæt på C++ i performance, så det virker lidt skråsikkert at kalde C++ "DET
bedste valg".
> og vi har valgt at leve med dem, da
> der ikke er noget
> bedre alternativ lige for tiden.
Jamen, det har jeg da også selv til nogen ting. Jeg bruger selv C++ til de
ting hvor der ikke er nogen åbenlyst gode alternativer. Desuden programmerer
jeg i C++ fuldtids, så man må sandelig sige at jeg "vælger at leve C++'s
ulemper".
> Og så syntes jeg ærligt talt du har givet fint udtryk for dine fine
> fornemmelser mht C++,
> i tråde hvor det har været rimeligt irrelevant, og vil foreslå dig
Må man nu ikke diskutere sprog og designprincipper på et lidt uformelt plan?
Jeg synes nærmere det virker som om denne gruppe har fine fornemmelser på
C++'s vejne, og at nogle lader til at have nogle briller på der ikke kan se
C++'s mangler.
(Jeg siger "lader til" - det er *mit* indtryk - jeg siger ikke at det er
sådan, men at det objektivt set er det subjektive indtryk jeg får).
> at starte et tråd, hvis du har noget du gerne vil diskutere.
Jamen tråde er jo træstrukturerede, så hvert svar starter jo en ny
(under)tråd.
Jeg kan ikke se meningen med at afbryde et naturligt flow i en tråd for at
starte en ny. Eller er det bare et nyt subject, du vil have?
Endelig er der jo også den mulighed at du kan springe over mine indlæg.
Bjarke
| |
Mogens Hansen (03-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 03-08-02 08:57 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message news:pDF29.1333
[8<8<8<]
> ..., jeg kommer blot med mine
> syn på visse uheldige aspekter af bl.a. C++.
Forkert igen.
Du kommer med en række ufunderede og fejlagtige påstånde, som om det er
objektive sandheder.
Se mit andet indlæg, for en nogenlunde komplet liste fra denne tråd.
Venlig hilsen
Mogens Hansen
| |
Jonas Meyer Rasmusse~ (03-08-2002)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 03-08-02 16:31 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:pDF29.1333$G3.124958@news010.worldonline.dk...
> "Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> wrote in message
> news:aif3o9$ng6$1@eising.k-net.dk...
>
> > Du putter jo netop folk i kasser! Det samme gælder, når du i dit korstog
> for
> > at hive folk
> > væk fra C++, antager at den generelle læser af denne gruppe ikke er
> > kompetent nok
> > til at foretage valg af sprog
>
> Der er jo ingen "generel læser" af denne gruppe. Nogle af meget
> velbevandrede i C++, mens andre knapt kan skrive en Hello, World! Intet
> indlæg kan ramme alles interesse, og jeg er da ked af hvis jeg har skudt
> under dit mål med ting der er trivialiteter for dig.
> Jeg forsøger iøvrigt ikke at vælge sprog for nogen, jeg kommer blot med
mine
> syn på visse uheldige aspekter af bl.a. C++. Disse ting er måske
> ligegyldigheder for dem som godt kender alle problemerne og af en eller
> anden grund (fx performancekrav) vælger at leve med dem. For andre kan det
> måske være godt nok at få lidt "second opinion" på forskellige
anbefalinger.
> Skulle dette ikke være tilfældet, undskylder jeg at have spildt folks tid.
Pointen var at du puttede Mogens i en kasse, lige efter du skrev at du ikke
ville putte ham i
en kasse.
> > - ja, du skriver endda at begejstrede C++
> > brugere ville skifte hvis
> > de så på et andet sprog.
>
> Jaja, må der være plads til lidt sarkasme og "language pissing contest"?
;)
Jeg syntes det er nedgørende og upassende, da du kører alle over en kam.
Iøvrigt syntes jeg sjældent sarkasme er passende, da man har svært ved at
vide
om modtagerne forstår budskabet, når vi benytter et tekstuelt medie.
>
> > Du er naiv, hvis du tror at alle C++ brugere ikke har overvejet deres
> valg,
> > og aldrig har programmeret i andet end C++.
>
> Der er da mange grunde til at folk bruger C++.
> Nogle har et godt kendskab til flere forskellige slags programmeringssprog
> og vælger C++ til de opgaver hvor det er et godt valg.
> Men jeg ved da at mange programmerer i C og C++, simpelthen fordi de ikke
> *kender* noget potentielt alternativ - ikke fordi de har valgt C eller C++
> blandt mange muligheder. Man kan vel altid slå lidt på tromme for at
udvide
> ens horisont.
Ja, nu er jeg jo stadig studerende, så de fleste jeg kender til kender
_mange_ andre sprog
end C++. Og de af de folk jeg kender som _låser_ sig til et sprog, er der
lige mange der vælger
Visual Basic, C++, osv.. ja, der er endda nogen der _kun_ vil bruge python..
problemet er ikke kun eksisterende i C++ verdenen.
[snip]
> > Udover ydelsen,
> > så kommer der faktisk de fordele som du klippede ud fra BS' faq - vel og
>
> Jeg klippede dem netop ud for at prøve at argumentere for at det ikke var
> fordele. Det er selvfølgelig rigtigt at C++ er mere udtryksfuldt end C,
men
> de andre såkaldte fordele mener jeg BS griber ud af luften.
Nej absolut ikke, hans påstande giver mening.
> > Og Ja, du har ret, der er nogen pitfalls i C++, og det kan være svært,
men
> > det er stadig det bedste valg, hvis man vægter performance højt,
>
> Tja, C og C++ ligger i hvert fald *blandt* de gode valg, hvis performance
er
> et knald-eller-fald kriterie. Der er andre programmeringssprog der kommer
> tæt på C++ i performance, så det virker lidt skråsikkert at kalde C++ "DET
> bedste valg".
Personligt har jeg ikke hørt om noget sprog der tilbyder de samme
faciliteter og
samme performance mål som C++ har, men jeg vil da gerne høre om et?
[snip]
> > Og så syntes jeg ærligt talt du har givet fint udtryk for dine fine
> > fornemmelser mht C++,
> > i tråde hvor det har været rimeligt irrelevant, og vil foreslå dig
>
> Må man nu ikke diskutere sprog og designprincipper på et lidt uformelt
plan?
> Jeg synes nærmere det virker som om denne gruppe har fine fornemmelser på
> C++'s vejne, og at nogle lader til at have nogle briller på der ikke kan
se
> C++'s mangler.
Tjae, du sætter os i en kasse igen, og jeg ved ikke hvordan du på nogen måde
kan vurdere at vi har fine fornemmelser?
> > at starte et tråd, hvis du har noget du gerne vil diskutere.
>
> Jamen tråde er jo træstrukturerede, så hvert svar starter jo en ny
> (under)tråd.
> Jeg kan ikke se meningen med at afbryde et naturligt flow i en tråd for at
> starte en ny. Eller er det bare et nyt subject, du vil have?
Det er klart at en diskussion kan udvikle sig, men når du præsenterer
funktioner som denne:
const std::string& Foo::get(const std::string& defaultValue)
{
if (isSet) return myVal;
else return defaultValue;
}
i en tråd startet af en nybegynder, der vil vide, så er det efter min mening
tydeligt at du er drejet
helt af sporet, og koncenterer dig om dit korstog mod C++ istedet for blot
at nævne at der er nogle
ting som ikke er helt åbenlyse i C++, og at det måske kunne være smartere at
begynde med et simplere sprog.
mvh Jonas
| |
Bjarke Dahl Ebert (03-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 03-08-02 19:23 |
|
"Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> wrote in message
news:aigsvh$fnn$1@eising.k-net.dk...
> > Jaja, må der være plads til lidt sarkasme og "language pissing contest"?
;)
> Jeg syntes det er nedgørende og upassende, da du kører alle over en kam.
> Iøvrigt syntes jeg sjældent sarkasme er passende, da man har svært ved at
> vide om modtagerne forstår budskabet, når vi benytter et tekstuelt medie.
Det kan der være noget om. Jeg har i hvert fald oplevet, ikke mindst i denne
tråd, at være blevet misforstået. Ytringer skal ikke altid opfattes så
bombastisk som de er sagt. Jeg skal åbenbart gøre mig mere umage med at sige
tingene lige ud, da det jeg skriver har det med at blive forstået mere
bogstaveligt end meningen var.
> Og de af de folk jeg kender som _låser_ sig til et sprog, er der
> lige mange der vælger
> Visual Basic, C++, osv.. ja, der er endda nogen der _kun_ vil bruge
python..
> problemet er ikke kun eksisterende i C++ verdenen.
Det er der jo heller ikke noget der har sagt. Der er også mange der sværger
til Java og ikke vil høre tale om at man kan bruge andet.
Nu ved jeg ikke om den med Python var møntet på mig , men jeg koder altså
i både Python, Java, C og C++, og jeg kender mange andre sprog, men bruger
dem ikke, fordi førnævnte fire sprog dækker et tilstrækkeligt bredt spektrum
for mig.
> > Tja, C og C++ ligger i hvert fald *blandt* de gode valg, hvis
performance
> er
> > et knald-eller-fald kriterie. Der er andre programmeringssprog der
kommer
> > tæt på C++ i performance, så det virker lidt skråsikkert at kalde C++
"DET
> > bedste valg".
>
> Personligt har jeg ikke hørt om noget sprog der tilbyder de samme
> faciliteter og
> samme performance mål som C++ har, men jeg vil da gerne høre om et?
Et sprog der kommer tæt på C++'s performance er O'Caml.
Disclaimer: O'Caml tilbyder ikke de samme faciliteter som C++ - det vil jeg
gerne med det samme understrege at jeg IKKE påstår. På samme måde tilbyder
C++ ikke de samme faciliteter som O'Caml
Referenceimplementationen af O'Caml indeholder en bytecode-compiler og
fortolker, samt en native code compiler til de mest populære platforme.
Der er en gut der har en ret seriøs sammenligning mellem mange forskellige
sprog. Han har implementeret en række benchmark-opgaver i alle disse sprog,
og giver point for CPU-tid, memoryforbrug og linier kode. Sådan en "test" er
selvfølgelig altid med forbehold for en masse ting (fx at de forskellige
implementationer er fair over for sprogene).
Men her er resultaterne, døm selv:
http://www.bagley.org/~doug/shootout/craps.shtml. I flere af benchmarks'ene
klarer O'Caml sig bedre end C++ - døm selv om han har været fair mod C++.
O'Caml er desuden er meget interessant sprog. Det har et meget innovativt
typesystem, baseret på ML med interessante udvidelser. Det er
"memorysikkert" (programmer kan ikke crashe) og typesikkert (typesystemet er
såkaldt "sundt").
> Det er klart at en diskussion kan udvikle sig, men når du præsenterer
> funktioner som denne:
> [...]
> i en tråd startet af en nybegynder, der vil vide, så er det efter min
mening
> tydeligt at du er drejet
> helt af sporet, og koncenterer dig om dit korstog mod C++ istedet for blot
> at nævne at der er nogle
> ting som ikke er helt åbenlyse i C++, og at det måske kunne være smartere
at
> begynde med et simplere sprog.
Okay, taget til efterretning
Mvh. Bjarke
| |
Jonas Meyer Rasmusse~ (03-08-2002)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 03-08-02 21:49 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:0eV29.2604$G3.201937@news010.worldonline.dk...
[snip]
> Et sprog der kommer tæt på C++'s performance er O'Caml.
> Disclaimer: O'Caml tilbyder ikke de samme faciliteter som C++ - det vil
jeg
> gerne med det samme understrege at jeg IKKE påstår. På samme måde tilbyder
> C++ ikke de samme faciliteter som O'Caml
> Referenceimplementationen af O'Caml indeholder en bytecode-compiler og
> fortolker, samt en native code compiler til de mest populære platforme.
>
> Der er en gut der har en ret seriøs sammenligning mellem mange forskellige
> sprog. Han har implementeret en række benchmark-opgaver i alle disse
sprog,
> og giver point for CPU-tid, memoryforbrug og linier kode. Sådan en "test"
er
> selvfølgelig altid med forbehold for en masse ting (fx at de forskellige
> implementationer er fair over for sprogene).
> Men her er resultaterne, døm selv:
> http://www.bagley.org/~doug/shootout/craps.shtml. I flere af
benchmarks'ene
> klarer O'Caml sig bedre end C++ - døm selv om han har været fair mod C++.
>
> O'Caml er desuden er meget interessant sprog. Det har et meget innovativt
> typesystem, baseret på ML med interessante udvidelser. Det er
> "memorysikkert" (programmer kan ikke crashe) og typesikkert (typesystemet
er
> såkaldt "sundt").
Funktionsprogrammering varmer indeni... selv når det er igennem C++'s
template system :)
Jeg var ikke klar over der var en ML dialekt, som havde så god ydelse
mvh
Jonas
| |
Per Abrahamsen (04-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 04-08-02 21:25 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> "Bjarne Stroustrup"-skolen mener at man skal kaste sig lige ud i C++, og at
> C er et laverestående sprog som man godt kan undvære.
>
> Andre, inkl. undertegnede, mener at man måske godt kan se nogle
> "Hello, World!" eksempler i C++, og også lave en std::string eller
> to, og måske ligefrem en std::vector, og sortere den, men hvis man
> rigtigt vil *forstå* C++ kan man efter min bedste overbevisning ikke
> slippe for at lære "C-delen" af C++ godt at kende (jaja,
> standardsvaret er at C ikke er en delmængde af C++, men det vil jeg
> altså kalde det i praksis). Et af C++'s vigtigste designkriterier
> har været binær kompatibilitet med C (udover "performance for enhver
> pris"). Derfor kan man ikke forstå C++ uden at forstå C, IMHO.
Du stiller de to skoler op mod hinanden som om de er modstridende.
Jeg mener, ligesom Bjarne Stroustrup og Mogens Hansen, at man med
fordel kan starte med at lærer C++'s højniveau fasciliteter, før man
lærer de lavniveau dele der stammer fra C, men at de sidste
naturligvis også er nødvendige for en fuld forståelse af C++.
Ser du selv den modstrid, eller er det en bevidst løgn fra din side?
Uanset om det er en bevidst løgn eller et hændeligt uheld, så synes
jeg du bør afholde dig fra at "vejlede" nye brugere. Et er at komme
med uigennemtænkte eller provokerende påstande overfor erfarne folk
som mig eller Mogens, men blandt venligst begynderne ude fra det.
Hvad ville du synes om hvis tilhængere af andre sprog kom med den
slags "oplysning" til begyndere i en gruppe omhandlende dit
favoritsprog?
| |
Bjarke Dahl Ebert (04-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 04-08-02 23:46 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
news:rjado2tlry.fsf@zuse.dina.kvl.dk...
> Du stiller de to skoler op mod hinanden som om de er modstridende.
Okay, lad os gøre et forsøg på at begynde en mere konstruktiv debat - jeg
indrømmer gerne at jeg ikke har været specielt konstruktiv selv, men det
synes jeg altså ikke jeg er ene om
Vi kan begynde med at bringe terminologien på plads . Lad mig bare droppe
"BS-skolen"-betegnelsen, den betegnelse bidrog nok ikke til det
konstruktive, eller den var i hvert fald med til at bringe diskussionen af
sporet - det var overhovedet ikke meningen med den.
Så jeg vil foreslå følgende mere neutrale betegnelser (så kan man selv
vurdere hvem der tilhører hvilke skoler, hvilken (om nogen) man selv
tilhører, og om skolerne overhovedet er "inhabitated").
Følgende er således blot definitioner, ikke påstande om hvad nogen (andre
end mig selv) mener.
Top-Down skolen mener at man i C++ bør starte med højniveaukonstruktionerne
og først senere introducere mere lavniveauting som fx pointere, den
"rigtige" forklaring på hvad referencer er, dynamisk allokering og typecast.
Bottom-Up skolen mener at man i C++ bør starte med lavniveautingene og først
senere introducere de mere højniveau ting, forklaret ud fra hvordan de
bygger ovenpå lavniveau-tingene.
Fælles for begge skoler er vist at man mener at "det hele" før eller siden
skal præsenteres. Det er nok kun rækkefølgen der er stridspunktet.
Det skulle vist være klart at jeg bekender mig til B.U., og jeg må derfor
spørge jer andre: har jeg været fair i beskrivelsen af T.D.-skolen?
Er det den relevante opdeling? Jeg vil meget gerne rettes hvis I ser verden
anderledes, sådan at vi ikke (igen) render ind i misforståelser og taler
forbi hinanden.
Her kommer min forklaring på hvorfor B.U. efter min mening er bedre end T.D.
til læring af C++. Så kan vi jo se hvor i kæden af konklusioner det er at
kæden falder af mellem os
Lavniveau-ting er maskinnære og handler om ting der er relevante for bl.a.
CPU'en. Højnievau-ting har det med at være tættere på det niveau vi
mennesker kan lide at tænke på, og tættere på formuleringen af de problemer
(eller løsningen på disse) der typisk optræder i programmeringsopgaver.
Derfor skulle man synes at det altid er bedst at tænke i termer af
højniveaukonstruktioner. Sådan burde det være i et ideelt (utopisk)
programmeringssprog. Kun når man har brug for lavniveau-ting, fx til at
tilgå systemressourcer der kun kan tilgås den vej, eller for at vride det
sidste performance ud af et programmet, burde der være behov for at bryde
sit lille hoved med lavniveau-issues.
C++ har en filosofi der hedder "what you don't use, you don't pay for". Jeg
tror at der med "pay for" oftest tænkes på runtime-performance. Hvis vi lige
generaliserer den filosofi til også at dække andre slags omkostninger (fx
sværhedsgraden af design, udviklingstid, mv.) og overfører den til
høj-/lavniveau-skismaet, så burde det være sådan at hvis man ikke har brug
for lavniveauting, så skal man heller ikke betale for at de er der (i termer
af kompleksitet og frustrationer)
Men lavniveau er "slået til" hele tiden i C++, på godt og ondt. Man har ikke
garbage-collection, der er ingen automatiske runtimechecks (kun dem man selv
laver), dvs. specielt ingen arraybound-checking, check af at en reference
stadig peger på et gyldigt objekt, check af at objektet faktisk har den type
som pointervariablen er kvalificeret med, osv.
Forstå mig ret - jeg siger ikke at ovenstående er ubetinget dårligt. Det er
ikke ment som et korstog mod C++ - det er godt at der findes sprog på
forskellige niveauer. Ovenstående "mangler" bliver ligefrem en fordel til
systemprogrammering. Jeg nævner det bare som en del af forklaringen på BU
vs. TD.
Så i C++ kan man ikke bare glemme lavniveau'et, heller ikke når man benytter
højniveau-konstruktioner. I C++ er det ikke sådan at man har en slags
"black-box" med alt det grimme lavniveau pakket væk i, som man kun behøver
at åbne for når man har brug for at udtrykke sig på lavt niveau. Man kan
sige, "lavniveau'et er der hele tiden", og man er efter min mening hele
tiden tvunget til at tænke på det når man koder.
Top-Down skolen mener selvfølgelig heller ikke at man kan undgå at vide hvad
der sker på lavt niveau. Den mener blot at man kan vente med at forklare det
"til senere".
Bottom-Up skolen mener derimod at det bliver for sent. For at forklare hvad
"std::string mystr;" er, må man sige at det reserverer et stykke hukommelse
med navnet "mystr" og tillægger det streng-type. Desuden forsvinder dette
stykke hukommelse automatisk når man forlader scope, hvilket specielt
betyder at man ikke længere kan bruge det erklærede navn "mystr". Og hvis
man kalder en funktion f(string&), så kan f referere til dette stykke
hukommelse (og ændre det), ikke bare til værdien af strengen.
Nu mener jeg at man allerede er ovre i avancerede emner, der bedst forstås
hvis man ved hvordan C benytter C-stakken. Eller er der en smartere måde at
lære det på?
<slut på min forklaring>
Hvad siger I - giver det nogen mening?
> Jeg mener, ligesom Bjarne Stroustrup og Mogens Hansen, at man med
> fordel kan starte med at lærer C++'s højniveau fasciliteter, før man
> lærer de lavniveau dele der stammer fra C, men at de sidste
> naturligvis også er nødvendige for en fuld forståelse af C++.
Jep.
Det lyder som om jeg har været rimeligt fair mod den holdning i min
beskrivelse - eller hvad?
Nu kender jeg jo desværre ikke "Accelerated C++", så jeg kunne godt tænke
mig at vide:
Bruger man fx fra starten "const std::string&" som parametertype og lover at
forklare senere hvad det betyder? Eller bruger man "std::string" by value og
venter med "const std::string&" indtil man har forklaret hvad en reference
er?
> Ser du selv den modstrid, eller er det en bevidst løgn fra din side?
Modstrid mellem hvad? Hvis du mener modstrid mellem de to skoler som jeg
ovenfor kalder Top-Down og Bottom-Up, så 'ja'.
Man må vel vælge om man lærer C-delen af C++ først, eller om man kan vente
og så starte med mere højnivau-C++-ting.
Måske har jeg ikke forstået dit spørgsmål rigtigt? Skær det gerne ud i pap
for mig
> Uanset om det er en bevidst løgn eller et hændeligt uheld, så synes
> jeg du bør afholde dig fra at "vejlede" nye brugere. Et er at komme
> med uigennemtænkte eller provokerende påstande overfor erfarne folk
> som mig eller Mogens, men blandt venligst begynderne ude fra det.
Okay, jeg svarede Dan Christensen at man efter min mening roligt kan lære C
først, og der stoppede "vejledningen" så - jeg har ikke påstået andet. Det
blev fulgt af en temmelig lang forklaring, som jeg godt kan se vil være
volapyk for en der ikke kender C/C++. Nu var mit indlæg jo ikke en personlig
email til Dan Christensen, men sendt ud på hele gruppen (og var faktisk
teknisk set et svar til Mogens Hansen) - så må det være tilladt at forsøge
at underbygge sine påstande, også med begreber der ikke giver mening for
alle læsere.
> Hvad ville du synes om hvis tilhængere af andre sprog kom med den
> slags "oplysning" til begyndere i en gruppe omhandlende dit
> favoritsprog?
C++-programmører (og andre) er altid velkomne på comp.lang.python.
Når de går derfra igen, vil de måske have en slange hængende om skuldrene og
sige "SPAM" og "ni" hele tiden
Spøg til side - der er tit begyndere der skriver i comp.lang.python, og de
får oftest en ualmindelig god og venlig behandling. Og det sker selvfølgelig
at et begynderspørgsmål udvikler sig til en tråd om emner som begynderen
ikke fatter en brik af. Det synes jeg ikke gør spor. Begynderen får trods
alt svar på sit spørgsmål og får lejlighed til at se at der er "more to it"
("mere til det"? end man umiddelbart skulle tro.
Bjarke
| |
Jonas Meyer Rasmusse~ (05-08-2002)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 05-08-02 00:33 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:iji39.3151$G3.394539@news010.worldonline.dk...
> Bottom-Up skolen mener derimod at det bliver for sent. For at forklare
hvad
> "std::string mystr;" er, må man sige at det reserverer et stykke
hukommelse
> med navnet "mystr" og tillægger det streng-type. Desuden forsvinder dette
> stykke hukommelse automatisk når man forlader scope, hvilket specielt
> betyder at man ikke længere kan bruge det erklærede navn "mystr". Og hvis
> man kalder en funktion f(string&), så kan f referere til dette stykke
> hukommelse (og ændre det), ikke bare til værdien af strengen.
> Nu mener jeg at man allerede er ovre i avancerede emner, der bedst forstås
> hvis man ved hvordan C benytter C-stakken. Eller er der en smartere måde
at
> lære det på?
Nej, "reference" begerebet, "funktions" begrebet, og levetid for variable
kan da sagtens forklares
uden at snakke om C-stakken? Det er selvf. korrekt at opbygningen af syntaks
og semantik på
dette område hænger meget sammen med hvordan C er på dette område.. men
derfor er det _ingen_
grund til at forklare sådan nogle specifikke detaljer.. En nybegynder vil
have svært nok ved at forstå
det på et abstrakt niveau - og ved at forklare ham hvordan det fungerer
nedenunder opnår du kun _en_
ting du gør ham forvirret, fordi han endnu ikke engang har forstået på det
abstrakte niveau, hvad det
egentlig er en "funktion" er.
Netop ved at gå oppefra og ned, som du kalder det :), så undgår man denne
forvirring.
Ydermere, vil man kunne lave praktiske ting meget hurtigere.. lidt ligesom
du hurtigere
kunne komme igang med python, fordi python har konstruktioner der gør
tingene nemt.
Det _tæller_ for en nybegynder, at de kan lave et quiz-program efter de har
læst et par kapitler,
og det kan man næppe hvis man prøver at forklare det nedefra og op.
Iøvrigt, hvis man skal forklare C++ nedefra og op, hvorfor skal C så ikke
forklares nedefra og op?...
og hvis du skal forklare C nedefra og op, skal du så egentlig ikke starte
med en gennemgang af hvordan
en computer virker, og hvorfor?
mvh Jonas
| |
Bjarke Dahl Ebert (05-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 05-08-02 19:31 |
|
"Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> wrote in message
news:aikdig$12m$1@eising.k-net.dk...
> Netop ved at gå oppefra og ned, som du kalder det :), så undgår man denne
> forvirring.
Det er jeg meget enig i, for de sprog hvor det kan lade sig gøre.
Min pointe er bare at i C++ skinner lavniveau-issues igennem på højere
niveau. Der er så mange ting på højt niveau der vil virke mærkværdigt og
uforståeligt for en bruger der ikke ved hvad der foregår "længere nede".
I mange andre sprog (stort set alle andre, tror jeg), ville jeg også
anbefale at starte "oppe fra og ned", da man i det væsentlige kan ignorere
lavniveau-detaljer indtil der er brug for dem. Det mener jeg ikke man kan i
C++.
> Ydermere, vil man kunne lave praktiske ting meget hurtigere.. lidt ligesom
> du hurtigere
> kunne komme igang med python, fordi python har konstruktioner der gør
> tingene nemt.
Jeg kan sagtens følge den begrundelse. Og det virker fint i fx Java, Scheme
og Python, som alle er gode til at pakke implementationsdetaljer væk. Der
vil altid være nogle lavniveauting der skinner igennem i større eller mindre
grad (fx Javas skelnen mellem primitive typer og reference-typer (int og
Integer), der nok skyldes implementations-issues), men det er ikke noget som
brugeren vil *undre* sig specielt længe over
> Iøvrigt, hvis man skal forklare C++ nedefra og op, hvorfor skal C så ikke
> forklares nedefra og op?...
Fordi C er meget bedre til at gemme væk hvordan det er implementeret ovenpå
assembler, end C++ er til at gemme væk at det er implementeret oven på C.
Jeg behøver overhovedet ikke at vide at der er rigtig CPU-kode "under" mit
C-program, jeg kan tænke på C som en abstrakt maskine - eller på C som et
avanceret assemblersprog i sig selv. Jeg behøver ikke vide noget om
386-adresseringsmodes.
> og hvis du skal forklare C nedefra og op, skal du så egentlig ikke starte
> med en gennemgang af hvordan
> en computer virker, og hvorfor?
Nej, der er masser af niveauer hele vejen ned til det fysiske atom-niveau,
men alle niveauerne er gode til at "skjule" deres mere
implementationsmæssige detaljer.
Jeg kan lære om elektronik, specielt transistorer, kondensatorer og
resistorer, uden at forstå hvad der sker på atomart niveau. Selvfølgelig
skal jeg nok ned og forstå hvad der sker med atomerne og elektronerne, hvis
jeg vil forstå hvordan en transistor virker, men ikke hvis jeg bare skal
kunne sætte et fungerende kredsløb sammen. Selvfølgelig skinner lavniveau'et
igennem når en transistor begynder at ryge og lugte, og dermed kommer uden
for den abstraktion jeg havde i tankerne, så *helt* væk er lavniveauet
ganske vist ikke.
Jeg kan lære digitalelektronik (med NAND-gates osv) uden at forstå hvordan
de er implementeret v.hj.a. transistorer. Dvs. jeg kan abstrahere ting som
spænding væk, og blot tænke på gates som logiske kredsløb, der sender nuller
og ettaller rundt. Det kan endda implementeres mekanisk, uden at jeg
nødvendigvis opdager nogen forskel.
Jeg kan til en vis grad også sætte mig ind i arkitekturen inde i en moderne
CPU, uden at vide hvad en NAND-gate er. Her er abstraktionen dog ikke så
udpræget som på de andre niveauer.
Og jeg kan læse intel's Pentium-instruktionssæt-manual uden at vide hvordan
det er implementeret inde i CPU'en - for mig vil CPU'en bare være en
black-box der udfører min maskin-kode.
osv.
Det springende punkt er, at jeg ikke mener at C++ er god til at pakke
lowlevel-detaljer (pointere, memory-håndtering osv) væk fra det højrere
niveau.
Mvh. Bjarke
| |
Jonas Meyer Rasmusse~ (05-08-2002)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 05-08-02 21:29 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:AgA39.3574$G3.535672@news010.worldonline.dk...
> "Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> wrote in message
> news:aikdig$12m$1@eising.k-net.dk...
>
> > Netop ved at gå oppefra og ned, som du kalder det :), så undgår man
denne
> > forvirring.
>
> Det er jeg meget enig i, for de sprog hvor det kan lade sig gøre.
>
> Min pointe er bare at i C++ skinner lavniveau-issues igennem på højere
> niveau. Der er så mange ting på højt niveau der vil virke mærkværdigt og
> uforståeligt for en bruger der ikke ved hvad der foregår "længere nede".
> I mange andre sprog (stort set alle andre, tror jeg), ville jeg også
> anbefale at starte "oppe fra og ned", da man i det væsentlige kan ignorere
> lavniveau-detaljer indtil der er brug for dem. Det mener jeg ikke man kan
i
> C++.
Det _kan_ man. Den succes Accelerated C++ har mener jeg er bevis på dette.
Jeg kender et par stykker som er igang med Accelerated C++, og indtil videre
går det vist forrygende, de er ihvertfald alle begejstrede for bogen.
> > Ydermere, vil man kunne lave praktiske ting meget hurtigere.. lidt
ligesom
> > du hurtigere
> > kunne komme igang med python, fordi python har konstruktioner der gør
> > tingene nemt.
>
> Jeg kan sagtens følge den begrundelse. Og det virker fint i fx Java,
Scheme
> og Python, som alle er gode til at pakke implementationsdetaljer væk. Der
> vil altid være nogle lavniveauting der skinner igennem i større eller
mindre
> grad (fx Javas skelnen mellem primitive typer og reference-typer (int og
> Integer), der nok skyldes implementations-issues), men det er ikke noget
som
> brugeren vil *undre* sig specielt længe over
Så Java har altså også problemet.. Og python sikkert også, bare i mindre
grad..
du _skal_ jo vide om argumentet bliver givet med som reference, eller som
værdi.
og du skal vide, at når du kalder rekursivt, så bliver der "lavet" nye
variable ved indgangen
til funktionen.. det sker alt sammen vha stakken, uanset om det er
C++,C,java,scheme eller python,
og ingen af stederne har man brug for at vide sådanne
implementationsdetaljer.
> > Iøvrigt, hvis man skal forklare C++ nedefra og op, hvorfor skal C så
ikke
> > forklares nedefra og op?...
>
> Fordi C er meget bedre til at gemme væk hvordan det er implementeret
ovenpå
> assembler, end C++ er til at gemme væk at det er implementeret oven på C.
> Jeg behøver overhovedet ikke at vide at der er rigtig CPU-kode "under" mit
> C-program, jeg kan tænke på C som en abstrakt maskine - eller på C som et
> avanceret assemblersprog i sig selv. Jeg behøver ikke vide noget om
> 386-adresseringsmodes.
Jeg syntes du ser forkert på det.
Mit syn er således
C er som det er, fordi der var brug for et sprog som var nært på den moderne
datamaskine,
med maksimal ydelse, og samtidig nogle konstruktioner til at gøre
implementationen lettere.
C++ er som det er, fordi det (ligesom C), har en målsætning om maksimal
ydelse.
Hoveddelen af det af C++,som kommer fra C, kommer derfra, pga ydelsen. Når
man
I C++ skal lære om en pointer, så er det _ikke_ noget C++ har arvet fra C,
men noget C++ har
pga strukturereringen af den moderne datamaskine, og ønsket om maksimal
ydelse. Sådan er det
for stort alt det C, man har behov for at vide i C++.. arven af disse dele
kommer, efter min mening,
hovedsagligt pga maskinens opbygning.
[klip]
> Det springende punkt er, at jeg ikke mener at C++ er god til at pakke
> lowlevel-detaljer (pointere, memory-håndtering osv) væk fra det højrere
> niveau.
C++ _kan_ pakke det ind, men der er også mulighed for rå tilgang..
Det kan der vel ikke være tvivl om ?
mvh Jonas
| |
Igor V. Rafienko (05-08-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 05-08-02 11:01 |
|
[ Bjarke Dahl Ebert ]
[ snip ]
> Men lavniveau er "slået til" hele tiden i C++, på godt og ondt. Man
> har ikke garbage-collection, der er ingen automatiske runtimechecks
> (kun dem man selv laver), dvs. specielt ingen arraybound-checking,
> check af at en reference stadig peger på et gyldigt objekt, check af
> at objektet faktisk har den type som pointervariablen er
> kvalificeret med, osv.
Og _alt_ dette kan fåes med en skikkelig implementasjon. Det at en god
del _velger_ å ikke bruke slike teknikker er en annen sak.
[ snip ]
> Så i C++ kan man ikke bare glemme lavniveau'et, heller ikke når man
> benytter højniveau-konstruktioner.
For en viss definisjon av lavnivå:
I'm normally not caring about writing memory management stuff in C++:
This is done by the classes I'm using.
-- Dietmar Kuehl, <news:comp.lang.c++.moderated>
Nå koder ikke jeg C++ på daglig basis, men jeg kan ikke huske når jeg
brukte arrays i C++ siste gang.
[ snip ]
> Bottom-Up skolen mener derimod at det bliver for sent. For at
> forklare hvad "std::string mystr;" er, må man sige at det reserverer
> et stykke hukommelse med navnet "mystr" og tillægger det
> streng-type.
Absolutt ikke! Det eneste man trenger å forklare er at det overnevnte
er en definisjon på lik linje med
int x;
og _nøyaktig_ de samme reglene gjelder hva angår skop. Det er
_overhodet_ ikke nødvendig å nevne _noe som helst_ om memory
allokering. Det er en strengtype, som inneholder tekst. _Hvorfor_
ønsker _du_ å fortelle til nybegynnere at det gjøres en new[]/malloc
som får en tilsvarende delete[]/free idet man forlater skopet?
> Desuden forsvinder dette stykke hukommelse automatisk når man
> forlader scope, hvilket specielt betyder at man ikke længere kan
> bruge det erklærede navn "mystr". Og hvis man kalder en funktion
> f(string&), så kan f referere til dette stykke hukommelse (og ændre
> det), ikke bare til værdien af strengen. Nu mener jeg at man
> allerede er ovre i avancerede emner, der bedst forstås hvis man ved
> hvordan C benytter C-stakken. Eller er der en smartere måde at lære
> det på?
D'uh.
For det første er det uproblematisk å legge seg på verdisemantikk
under opplæringen. Inntil folk har nok kunnskaper, er det bare å bruke
void process( std::string s );
heller enn
void process( const std::string &s );
For det andre er det bare to ting man trenger å forklare om
references, og _det_ burde folk greie å mestre (vel å merke, man
trenger ikke å fortelle så veldig mye om pekere, når man snakker om
references, uansett hvordan disse burde implementeres), spesielt gitt
at det ikke er noen forskjell mellom int& og std::string& hva disse
tingene angår.
[ snip ]
> C++-programmører (og andre) er altid velkomne på comp.lang.python.
> Når de går derfra igen, vil de måske have en slange hængende om
> skuldrene og sige "SPAM" og "ni" hele tiden
"ni"?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Mogens Hansen (05-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-08-02 20:55 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:iji39.3151$G3.394539@news010.worldonline.dk...
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
> news:rjado2tlry.fsf@zuse.dina.kvl.dk...
>
> > Du stiller de to skoler op mod hinanden som om de er modstridende.
>
> Okay, lad os gøre et forsøg på at begynde en mere konstruktiv debat - jeg
> indrømmer gerne at jeg ikke har været specielt konstruktiv selv, men det
> synes jeg altså ikke jeg er ene om
Antyder du at jeg ikke har været konstruktiv ?
Jeg startede med at give Dan Christensen et seriøst og konstruktivt svar på
et legitimt spørgsmål.
Derefter kom du med den ene ufunderede påstand efter den anden (jeg skal nok
lade være med at gentage dem igen igen).
Hvis du læser tråden igennem igen, vil du se at jeg stort set ikke har lavet
andet end at påpege faktuelle fejl i de udsagn du er kommet med - uanset
hvor ligegyldige de måtte være for Dan Christensen og andre med tilsvarende
spørgsmål.
Du kan da ikke mene at det ikke er konstruktivt at påpege hvad der er
objektivt rigtigt og hvad der er forkert.
Alt andet er da at vildledning af nytilkomne, hvilke er destruktivt.
Jeg kan forstå at det føles irriterende og generende - men det må man
nødvendigvis leve med når man ytrer sig i et offentligt forum. Og det er
hævet over enhver tvivl at det var nødvendigt.
[8<8<8<]
> Er det den relevante opdeling?
Den opdeling forekommer mig at tage udgangspunkt i enkelte sprogfeatures.
For mig er sprogfeatures golde, hvis de ikke ses i sammenhæng med de design
og programmeringsstile de understøtter.
Jeg vil hellere tage udgangspunkt i programmeringsstile, og først lære
nytilkomne stile som er enkle, sikre, fleksible og hyppigt brugbare i
udviklingen af applikationer (i modsætning til udvikling af biblioteker).
Samtidig skal det være programmeringsstile som holder til komplekse
programmer.
De krav er opfyldt i min anbefaling til Dan Christensen.
Derfor vil jeg starte med at give nytilkomne den vane at bruge std::string
frem for char*, vector frem for array etc.
Jeg anser det ikke for en forudsætning at vide hvad "class", "template" og
"string litteral" er for at kunne bruge string og vector.
Jeg vil opfordre til en stil, hvor nytilkomne hurtigt får nogle
successoplevelser med at lave forholdsvis nyttige programmer.
Jeg vil gerne holde det "hemmeligt" et godt stykke tid at man kan lave
preprocessor makroer, så man ikke får det som vane.
Jeg vil gerne vente med at forklare om "printf", fordi den har en række
problemer (potientiel buffer-overrun, manglende compile-time typecheck
etc.). Primært syntes jeg "printf" er relevant, for at man skal være i stand
til at lære og forstå kode, der bruger det.
Jeg vil vente med emner som template metaprogrammering til sent, fordi det
mest er nyttigt at skrive i forbindelse med udvikling af biblioteker.
[8<8<8<]
> Lavniveau-ting er maskinnære og handler om ting der er relevante for bl.a.
> CPU'en. Højnievau-ting har det med at være tættere på det niveau vi
> mennesker kan lide at tænke på, og tættere på formuleringen af de
problemer
> (eller løsningen på disse) der typisk optræder i programmeringsopgaver.
> Derfor skulle man synes at det altid er bedst at tænke i termer af
> højniveaukonstruktioner. Sådan burde det være i et ideelt (utopisk)
> programmeringssprog.
Enig
[8<8<8<]
> Men lavniveau er "slået til" hele tiden i C++, på godt og ondt.
Sådan oplever jeg det ikke, når jeg sidder og bruger C++ til hverdag.
Det er da rigtigt at for at kunne spille på alle strenge i C++ skal man have
en forståelse for mange niveauer. Det er da en fordel at spænde fra
at vide hvordan alle C++ konstruktioner mapper til assembler
til
at vide hvordan man laver template meta programmering.
Men ingen af de ekstremer er nødvendige for at komme i gang med at lære C++,
og isærdeleshed er det ikke nødvendigt for at skrive "almindelige" nyttige
programmer.
Det er nødvendigt at vide temmeligt meget, ikke blot om sproget men
softwaredesign generelt, for at skrive gode biblioteker. I særdeleshed skal
man vide meget for at skrive exeptionelle biblioteker som STL (her taler jeg
ikke af erfaring).
> Man har ikke
> garbage-collection, der er ingen automatiske runtimechecks (kun dem man
selv
> laver), dvs. specielt ingen arraybound-checking, check af at en reference
> stadig peger på et gyldigt objekt, check af at objektet faktisk har den
type
> som pointervariablen er kvalificeret med, osv.
De automatiske runtimecheck kan du sagtens få (under udvikling) ved f.eks.
at enable CodeGuard switchen eller bruge tilsvarende værktøjer.
Jeg vil nødig starte en diskution af garbage-collection - men det løser
bestemt ikke alle problemer og skaber sine egne problemer (i hvertfald i den
udformning det har i Java og C# (CLR)).
Der findes som bekendt kommercielle værktøjer til at diagnosticere
memory-problemer i Java, og jeg tør godt spå at det også kommer til .NET
platformen.
[8<8<8<]
> Det er
> ikke ment som et korstog mod C++
Det bliver du vist nød til at sige mere end een gang før jeg tror på det
(jeg vil undlade at finde citater fra denne tråd).
> - det er godt at der findes sprog på
> forskellige niveauer.
C++ har et stort dynamik område, og er i sig selv et sprog med forskellige
niveauer.
Bl.a. derfor tager det tid at mestre.
Men C++ er et professionelt værktøj til kompentente brugere.
Hvor lang tid tager det en kirurg at meste noget så simpelt som en kniv ?
[8<8<8<]
> Det lyder som om jeg har været rimeligt fair mod den holdning i min
> beskrivelse - eller hvad?
Som sagt, mit fokus ligger på parametre som programmeringsstil og
anvendelighed.
Dine oprindelig svar på mit indlæg var langt fra fair eller sagligt.
>
> Nu kender jeg jo desværre ikke "Accelerated C++", så jeg kunne godt tænke
> mig at vide:
> Bruger man fx fra starten "const std::string&" som parametertype og lover
at
> forklare senere hvad det betyder? Eller bruger man "std::string" by value
og
> venter med "const std::string&" indtil man har forklaret hvad en reference
> er?
Den bruger slet ikke funktioner (bortset fra main) fra starten.
Først fra side 51, i kapitlet "Organizing programs and data", beskrives
funktioner.
Side 53: call by value.
Side 54: call by reference
Side 58: call by const reference.
Det burde vist tilfredsstille de fleste med hensyn til indhold og tempo.
Bemærk iøvrigt at reference en C++ ting og ikke en C89 ting (jeg ved ikke om
det er med i C99, men jeg har ikke set det).
[8<8<8<]
> Okay, jeg svarede Dan Christensen at man efter min mening roligt kan lære
C
> først, og der stoppede "vejledningen" så - jeg har ikke påstået andet.
Bemærk at jeg på _intet_ tidspunkt har anfægtet din ret til at sige at Dan
Christensen roligt kan lære C først.
Jeg har påstået at det er en omvej at lære C først, hvis man ønsker at lære
C++, men at det bestemt ikke er spild.
Jeg har primært korrigeret dine udsagn hvor de har været ufunderet og kun
baseret på din egen forudindtagethed eller hvor de har været direkte
forkerte, med præcis henvisning til kilde.
[8<8<8<]
> Nu var mit indlæg jo ikke en personlig
> email til Dan Christensen, men sendt ud på hele gruppen (og var faktisk
> teknisk set et svar til Mogens Hansen) ...
Et af de væsentlige problemer er netop at du svarede på mit indlæg.
Som det er kommet frem i denne tråd og som jeg forventede, kender du ikke
"Accelerated C++". Derfor ikke noget fundament overhovedet for at have en
mening om hvad mit svar _faktisk_ indebærer for Dan Christensen. Det eneste
du har i den sammenhæng er din egen forudindtagethed, som forekommer
kraftigt påvirket af det faktum at du syntes C++ er noget skrammel.
Hvis du havde svaret direkte på Dan Christensen spørgsmål, kommet med din
anbefaling af at han roligt kan lære C først, og havde undladt at de
kedelige ufunderede tilføjelse, ville jeg ikke have oponeret.
Jeg kunne endda forestille mig at du så havde fremstået seriøs og troværdig.
Din subjektive vurdering har samme eksistensberettigelse som min subjektive
vurdering.
Lad mig så lige forklare lidt om bogen "Accelerated C++", og dens baggrund:
Bogens forfattere har været involveret i såvel design som anvendelse af C++
fra starten af C++'s.
De arbejdede (ifølge Stan Lippman's bog) begge på "Foundation" projektet
under ledelse af Bjarne Stroustrup.
Barbara Moo var superviser for hele gruppen, undtaget Bjarne Stroustrup og
Andrew König.
Andrew Koenig er bestemt ikke et "C++ halleluja-fjols" der ikke kender andre
sprog.
Han er bl.a. forfatter af den meget anerkendte bog
C Traps and Pitfalls
Andrew Koenig
ISBN 0-201-17928-8
så han kender udemærket hvad man skal passe på i C.
Han kender desuden en lang række andre sprog - som bl.a. har været brugt i
forbindelse med produktionen af "Accelerated C++".
Hvis du søger på nyhedsgrupper på Andrew Koenig og Pyhton
( http://groups.google.com/groups?q=ark@research.att.com+Python&ie=UTF-8&oe=U
TF-8&hl=da) vil du se at han faktisk er forholdvis aktiv inden for Python.
(Det gælder, som Jonas Meyer Rasmussen har bemærket, at de fleste C++
programmører kender, bruger og har brugt andre sprog - mig selv inkluderet.
Det er useriøst, plat og fornærmende når du insinuerer andet.)
Bogen er baseret på _erfaring_ med undervisning i C++ fra det amerikanske
Stanford Universitet, hvor forfatterne gennem en årrække har afholdt et
intensivt uge kursus i C++.
På et tidspunkt ændrede de undervisningsstrategien, med en dramatisk
virkning. Det er den nye strategi som udgør rygraden i bogen.
Se "Our approach works -- for beginners and experience programmers" fra
forordet
( http://www.awprofessional.com/catalog/product.asp?product_id={4E5E634E-1443
-40CB-AEDB-91A48F02D3A9}&selectDescTypeId={0BBA7A1C-E080-49A0-B103-E1BE9F7C7
092}&st=5130B593-BAEC-49C6-B6A8-0035DFD1EA3B&session_id={1BF63F37-D221-434A-
8756-373D0A13461F})
Hvilken _erfaring_ med undervisning i C++ på forskellige måder har _du_ at
stille op med, når du giver råd ?
Bogens princip er at præsentere emnerne i den rækkefølge, der er behov for
dem for at skrive små nyttige programmer.
Det er ikke et spørgsmål om hvorvidt man for at lære C++ skal lære noget af
det subset der stammer fra C.
Enhver med blot et minimum at indsigt i de 2 sprog, ved at man ikke kan
skrive så meget som et Hello World program i C++ uden at komme i berøring
med C subsettet.
Ligeså snart man har skrevet
int main(void)
har man brugt dele af C subsettet.
Men en person der ønsker at lære C++ (som Dan Christensen gav udtryk for)
har ikke nogen glæde af at få at vide at det stammer fra C. Man kan
diskutere om han tager skade af det, men det øger alt andet lige mængden af
information som skal kaperes.
Det er ikke sprogene der er det mest interessant - det er design og
programmeringsstil.
Venlig hilsen
Mogens Hansen
| |
Anders J. Munch (05-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 05-08-02 00:14 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> skrev:
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> [snip]
> Jeg mener, ligesom Bjarne Stroustrup og Mogens Hansen, at man med
> fordel kan starte med at lærer C++'s højniveau fasciliteter, før man
> lærer de lavniveau dele der stammer fra C, men at de sidste
> naturligvis også er nødvendige for en fuld forståelse af C++.
Og jeg mener, at indtil man får lært C-delen af kernesproget, så må
resten af C++ være temmeligt forvirrende at have med at gøre.
Jeg tænker for eksempel på reglerne for iterator invalidering. Den
eneste grund til at jeg selv kan huske dem, er at jeg forstår hvordan
de forskellige container-klasser er implementeret. Hvis man skal lære
C++ på abstraktionsniveauet containere+iterators+algoritmer, så vil
iterator-invaliderings-reglerne være umotiveret udenadslære.
Bjarne Stroustrup har fra begyndelsen haft den glimrende politik, at
han ikke beskæftigede sig med sprogsammenligninger; i stedet har han
koncentreret sig om at fortælle hvad C++ kan.
I new_learning.pdf falder han i vandet: Artiklen handler ikke ret
meget om indlæring men meget om at vise hvor meget lettere
småprogrammer er at skrive i C++ end i C. Med tydelig bias: Opgaverne
er skræddersyet til C++, hans C-kode er elendig (programmet side 3 kan
stort set skrives på den halve plads), han foretager irrelevante
hastighedssammenligninger, han kritiserer sit stråmands-C-program for
at mangle fejlcheck men overser de (vigtigere!) fejlcheck der mangler
også i hans C++-programmer.
>
> Ser du selv den modstrid, eller er det en bevidst løgn fra din side?
>
> Uanset om det er en bevidst løgn eller et hændeligt uheld, så synes
> jeg du bør afholde dig fra at "vejlede" nye brugere. Et er at komme
> med uigennemtænkte eller provokerende påstande overfor erfarne folk
> som mig eller Mogens, men blandt venligst begynderne ude fra det.
Jeg synes Bjarkes påstande er generelt fornuftige, og jeg synes du er
unødigt grov her.
>
> Hvad ville du synes om hvis tilhængere af andre sprog kom med den
> slags "oplysning" til begyndere i en gruppe omhandlende dit
> favoritsprog?
Hvilken anden gruppe vil du da foreslå til at diskutere C og C++´s
relative meritter?
- Anders
| |
Mogens Hansen (05-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-08-02 20:55 |
|
"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:<zzi39.3159$G3.396686@news010.worldonline.dk>...
[8<8<8<]
> I new_learning.pdf falder han i vandet: Artiklen handler ikke ret
> meget om indlæring men meget om at vise hvor meget lettere
> småprogrammer er at skrive i C++ end i C.
Min _erfaring_ er at de overvejelser Bjarne Stroustrup gør i artiklen, netop
også skalerer godt til _store_ programmer.
Måden som folk bliver undervist på fra starten spiller en stor rolle for
hvordan de programmerer senere.
> Med tydelig bias: Opgaverne
> er skræddersyet til C++, hans C-kode er elendig (programmet side 3 kan
> stort set skrives på den halve plads),
Det er vel ikke sådan at du vil poste din udgave af hans C-program fra side
3 ?
Det er forbigået min opmærksomhed at det kan gøres væsentligt bedre.
> han foretager irrelevante
> hastighedssammenligninger,
Hastighedssammenligninger er ikke irrelevante.
Det er en almindelig bekymring i forhold til C++, hvis man kommer fra en C
baggrund.
> han kritiserer sit stråmands-C-program for
> at mangle fejlcheck men overser de (vigtigere!) fejlcheck der mangler
> også i hans C++-programmer.
Hvilke fejlcheck er det, der mangler i hans C++ programmer ?
Man kan selvfølgelig sige, at på side 2 burde der fanges en bad_alloc
exception og udskrives en fejlmelding, hvis de skal svare til programmet på
side 3. Men programmet opfører sig pænt og veldefineret i tilfælde af fejl.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 00:51 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aimlea$hik$1@news.cybercity.dk...
> [8<8<8<]
> > I new_learning.pdf falder han i vandet: Artiklen handler ikke ret
> > meget om indlæring men meget om at vise hvor meget lettere
> > småprogrammer er at skrive i C++ end i C.
>
> Min _erfaring_ er at de overvejelser Bjarne Stroustrup gør i artiklen,
netop
> også skalerer godt til _store_ programmer.
Men det hjælper jo ikke rigtig BS's artikel hvad din erfaring er, hvis BS
ikke henviser til din erfaring.
Anders har ret i at BS's artikel handler mere om nogle ligegyldige
kodesammenligninger, end om indlæring af C++.
*Mit* efterhånden meget langvarige bekendtskab med C++ fortæller mig at
store programmer (mange og skiftende udviklere over lang tid) lider under
C++, selv hvis alle benytter "C++-programmeringsstil".
C++-programmeringsstil er ikke én stil - alle kommer med hver sin
forestilling om hvad der er "pænt", og C++ tilbyder så mange måder at gøre
selv banale ting på at et stort stykke software til sidst er et miskmask af
wrappere og adapter-ting for at få det hele til at hænge sammen. Og når
tingene bliver store, så skal der bare være en pointerfejl i én linie kode
ud af en halv million, så vælter tårnet.
> Måden som folk bliver undervist på fra starten spiller en stor rolle for
> hvordan de programmerer senere.
Kender du nogen resultater der kan underbygge det? Det lyder som noget der
godt kan være en vis sandhed i, men det kunne også være grebet lige ud af
luften.
Jeg synes at der er indikationer på at det snarere er folks erfaring der har
betydning for hvordan de programmerer. Dvs. hvad har de prøvet at kode, hvor
store har tingene været, og hvilke sprog og værktøjer har de benyttet, og
ikke mindst: hvor længe. Hvordan man "fra starten" bliver undervist kan for
den sags skyld være i Commodore Basic, hvis de synes det er sjovt at spilde
tiden på det - jeg er ganske tryg ved at en almindeligt begavet programmør
godt kan omstille sig fra Basic til fx Scheme, og også formulere sig i gængs
Scheme-stil, når han/hun lærer det.
Den første måde at programmere på, varer alligevel kun indtil man lærer
noget nyt.
Dårlig programmeringsstil kan nok ikke forebygges ved at starte med at få
proppet "den gode stil" ind med skeer. Begynderen kan alligevel ikke se
forskel og fornemme hvornår det ene er bedre end det andet, endsige
værdsætte "det smarte" i den anbefalede løsning - det kræver erfaring.
Jeg tror desværre man er nødt til gøre alle fejltagelserne selv (eller
opleve dem på nært hold), og føle på egen krop hvilke problemer man så får.
Selvfølgelig kan man vejledes med gode råd, men der er nu ikke noget der får
en til at benytte dem, som det at måtte indrømme "jaja, det vidste vi godt
at man ikke skulle gøre, men NU kan vi se hvorfor".
"Jeg *tænkte* nok at det var en dum ide at lave et abstrakt
iterator-hierarki"
"Jeg *vidste* at jeg ikke skulle kode mit eget reflection i C++"
"De *sagde* jo at det var svært at lave cachen korrekt og trådsikker på den
måde, men ville jeg lytte?"
osv...
> > han foretager irrelevante
> > hastighedssammenligninger,
>
> Hastighedssammenligninger er ikke irrelevante.
> Det er en almindelig bekymring i forhold til C++, hvis man kommer fra en C
> baggrund.
Hastighedssammenligninger er temmelig irrelevante i en artikel der foregiver
at instruere i hvordan man bedst lærer C++.
Mvh. Bjarke
| |
Anders J. Munch (06-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 06-08-02 02:28 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> skrev:
>
> "Anders J. Munch" <andersjm@inbound.dk> wrote:
>
> [8<8<8<]
Det symbol kender jeg ikke?
> > I new_learning.pdf falder han i vandet: Artiklen handler ikke ret
> > meget om indlæring men meget om at vise hvor meget lettere
> > småprogrammer er at skrive i C++ end i C.
>
> Min _erfaring_ er at de overvejelser Bjarne Stroustrup gør i artiklen,
netop
> også skalerer godt til _store_ programmer.
> Måden som folk bliver undervist på fra starten spiller en stor rolle for
> hvordan de programmerer senere.
Enig. Jeg ser det som samme tankegang der ligger bag, når Eric Raymond
skriver: "LISP is worth learning for a different reason --- the
profound enlightenment experience you will have when you finally get
it. That experience will make you a better programmer [...]"[1]
Jeg tror derimod ikke på at
copy(buf.begin(),buf.end(),ostream_iterator<string>(fout, '\n'))
vil gøre nogen til en bedre programmør, hvis de ikke i forvejen har
fanget pointen, fx da de lærte et funktionsprogrammeringssprog. Det er
for tungt at danse med til at en begynder vil kunne værdsætte
fordelene.
Forresten tvivler jeg ikke på din erfaring -- hvad end du vælger for
kodestil, så vil du givetvis kunne få det til at skalere godt til
store programmer
>
> > Med tydelig bias: Opgaverne
> > er skræddersyet til C++, hans C-kode er elendig (programmet side 3 kan
> > stort set skrives på den halve plads),
>
> Det er vel ikke sådan at du vil poste din udgave af hans C-program fra
side
> 3 ?
> Det er forbigået min opmærksomhed at det kan gøres væsentligt bedre.
Så gerne .. her følger et program uden unavngivne magiske tal, uden
unødige casts, uden "0" brugt som hverken bogstav eller pointer, uden
isspace bug'en, uden prematur optimering og en del kortere end
Bjarnes.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
char const* ltrim(char const* s)
{
while(isspace((unsigned char)*s)) ++s;
return s;
}
int main()
{
char* name = NULL;
size_t len = 0;
int c;
printf("Please enter your first name:\n");
while((c = getchar()) != EOF && c != '\n')
{
name = realloc(name, len+2);
if(name == NULL) break;
name[len++] = c;
name[len] = '\0';
}
printf("Hello %s\n", name==NULL? "" : ltrim(name));
free(name);
}
>
> > han foretager irrelevante
> > hastighedssammenligninger,
>
> Hastighedssammenligninger er ikke irrelevante.
> Det er en almindelig bekymring i forhold til C++, hvis man kommer fra en C
> baggrund.
I en C++ advocacy artikel er hastighedssammenligninger relevante, og
Bjarne har i parentes bemærket fuldstændigt ret i alt hvad han skriver
om emnet. Men relevans for indlæring?
>
> > han kritiserer sit stråmands-C-program for
> > at mangle fejlcheck men overser de (vigtigere!) fejlcheck der mangler
> > også i hans C++-programmer.
>
> Hvilke fejlcheck er det, der mangler i hans C++ programmer ?
> Man kan selvfølgelig sige, at på side 2 burde der fanges en bad_alloc
> exception og udskrives en fejlmelding, hvis de skal svare til programmet
på
> side 3. Men programmet opfører sig pænt og veldefineret i tilfælde af
fejl.
Typisk start på main i artiklens programmer:
int main(int argc, char* argv[])
{
char* file = argv[2];
Behøver jeg kommentere det?
- Anders
[1] http://www.tuxedo.org/~esr/faqs/hacker-howto.html
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 13:59 |
|
"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:LaG39.3764$G3.610087@news010.worldonline.dk...
> "Mogens Hansen" <mogens_h@dk-online.dk> skrev:
> > [8<8<8<]
> Det symbol kender jeg ikke?
[] er array-index (eller kald af index-operator).
8<8<8 parses som (8<8)<8, som evaluerer til (true)<8 --> (1)<8 --> true.
Det sidste '<' er en syntaksfejl.
> Jeg tror derimod ikke på at
> copy(buf.begin(),buf.end(),ostream_iterator<string>(fout, '\n'))
>
> vil gøre nogen til en bedre programmør, hvis de ikke i forvejen har
> fanget pointen, fx da de lærte et funktionsprogrammeringssprog. Det er
> for tungt at danse med til at en begynder vil kunne værdsætte
> fordelene.
Ja, man forsøger at opfinde en "funktionel delmængde" af C++, implementeret
oven på det procedurelle og operator-overloading.
Selv som erfaren C++-programmør vælger man ofte at droppe ovenstående stil,
og i stedet kode rent procedurelt, da det er enklere at skrive og nemmere at
læse.
Stroustrup sagde engang at der inde i C++ er et mindre og pænere sprog
"struggling to get out".
Det må så være et sprog hvor man kan erstatte
copy(buf.begin(),buf.end(),ostream_iterator<string>(fout, '\n'))
med noget i stil med
for_each(buf, line_writer(fout))
> Forresten tvivler jeg ikke på din erfaring -- hvad end du vælger for
> kodestil, så vil du givetvis kunne få det til at skalere godt til
> store programmer
Ditto, jeg tvivler heller ikke på Mogens' evner til at skrive store
C++-programmer. Men det er desværre ikke alle programmører der er lige så
kvalificerede, og så går tingene galt.
> int main(int argc, char* argv[])
> {
> char* file = argv[2];
>
> Behøver jeg kommentere det?
Bjarke
| |
Mogens Hansen (06-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 06-08-02 20:34 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Stroustrup sagde engang at der inde i C++ er et mindre og pænere sprog
> "struggling to get out".
> Det må så være et sprog hvor man kan erstatte
> copy(buf.begin(),buf.end(),ostream_iterator<string>(fout, '\n'))
> med noget i stil med
> for_each(buf, line_writer(fout))
Som jeg opfatter det mindre og pænerere sprog, drejer det sig primært om at
rydde op i syntaksen, forenkle steder hvor man kan gøre det samme på flere
måder, gøre det simplere at komme igang.
Hvis man vil se en flig af hvordan syntaksen måske kunne være, så side 22 af
http://www.klid.dk/arrangementer/XTI_kbh.pdf
Men stadig med mange af de samme egenskaber, f.eks.:
* statisk typechecket
* understøttelse af mange programmeringsstile samtidig
* have et stort dynamikområde, der gør det mulighed for at skrive
effektive programmer samtidig med højniveau konstruktioner
* deterministisk objekt livstid
[8<8<8<]
> Men det er desværre ikke alle programmører der er lige så
> kvalificerede, og så går tingene galt.
Jeg har næsten altid været i den heldige og priviligerede situation at
arbejde sammen med dygtige, veluddannede kollegaer i miljøer hvor høj
kvalitet bliver værdsat.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 22:11 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aip81j$958$1@news.cybercity.dk...
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> > Stroustrup sagde engang at der inde i C++ er et mindre og pænere sprog
> > "struggling to get out".
>
> Som jeg opfatter det mindre og pænerere sprog, drejer det sig primært om
at
> rydde op i syntaksen, forenkle steder hvor man kan gøre det samme på flere
> måder, gøre det simplere at komme igang.
Opfatter du det som en "C++ revisited" der dropper bagudkompatibilitet på
betydningsfulde punkter, eller opfatter du det som en gradvis udlugning af
uønsket syntaks/"mekanismer" i en iterativ proces over flere år, hvor
softwaren kan nå at følge med?
Jeg mener at det mest realistiske vil være det første. Det ville nok blive
et meget anderledes sprog. Det kunne være interessant at se hvad der ville
ske hvis Stroustrup, Koenig og andre fik frie hænder til at "rydde op" i C++
uden at skulle tænke på kompatibilitet.
>
> Hvis man vil se en flig af hvordan syntaksen måske kunne være, så side 22
af
> http://www.klid.dk/arrangementer/XTI_kbh.pdf
Øh? Taler vi om siden med overskriften "External XTI"?
Deres Udsendte var selv til stede ved det foredrag og kan berette at
External XTI ikke er et forslag til ny C++ syntax. XTI er eXtended Type
Info. Det er BS's forslag til et menneskelæsbart format som compileren kan
hælde
typeinformation ud i, og som et program derefter kan læse ind og bruge som
en form for IDL. BS ønsker at bruge det til reflection og lignende.
Det er altså kun typer der kan beskrives i XTI, og det er output fra
compileren snarere end input til den.
Bjarke
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 05:40 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Øh? Taler vi om siden med overskriften "External XTI"?
Ja.
> Deres Udsendte var selv til stede ved det foredrag og kan berette at
> External XTI ikke er et forslag til ny C++ syntax. XTI er eXtended Type
> Info.
Jeg var også tilstede ved det foredrag på Vesterbro.
Nej, det er ikke direkte et forslag til en ny syntaks.
Jeg var også tilstede ved et foredrag et år senere, hvor Bjarne Stroustrup
præsentrede nogenlunde det samme. Tilstede var en lang række af verdens mest
kompetente C++ eksperter.
Det var Bjarne Stroustrup egne ord, at det var lidt af det mindre og pænere
sprog, der kiggede frem.
Det var _præcist_ også mit indtryk, fra foredraget på Vesterbro.
Du kan naturligvis have haft en anden oplevelse - det er bare synd for dig.
Som tankespind, blev det fra publikum diskuteret at lave en alternativ
syntaks - altså droppe sourcekode kompatibilitet fuldstændigt, men (stort
set) holde kompatibiliteten med objektmodellen.
Det skal siges, at det er var kun tankespind, og jeg har ikke kendskab til
at nogen arbejder med et sådant projekt.
> Det er altså kun typer der kan beskrives i XTI, og det er output fra
> compileren snarere end input til den.
Sagde jeg ikke at det kun var en lille flig ?
Det sprog, der er skitseret på siden, kan ikke læses af en eller anden
compiler ?
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 10:07 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:dZW39.4765$G3.742631@news010.worldonline.dk...
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
> news:aip81j$958$1@news.cybercity.dk...
[8<8<8<]
> > Hvis man vil se en flig af hvordan syntaksen måske kunne være, så side
22
> af
> > http://www.klid.dk/arrangementer/XTI_kbh.pdf
>
> Øh? Taler vi om siden med overskriften "External XTI"?
>
> Deres Udsendte var selv til stede ved det foredrag og kan berette at
> External XTI ikke er et forslag til ny C++ syntax. XTI er eXtended Type
> Info. Det er BS's forslag til et menneskelæsbart format som compileren kan
> hælde
> typeinformation ud i, og som et program derefter kan læse ind og bruge som
> en form for IDL. BS ønsker at bruge det til reflection og lignende.
> Det er altså kun typer der kan beskrives i XTI, og det er output fra
> compileren snarere end input til den.
At du kommer hjem til Århus kun med det helt konkrete indhold af foredraget
er naturligvis forståeligt, men beklageligt.
Det var et spændende foredrag, hvor der var en masse indhold udover det helt
konkrete: XTI.
Personligt fik jeg en masse inspiration og spændende arbejde ud af det.
Når jeg siger at man kan "se en flig af hvordan syntaksen måske kunne være",
så er det naturligvis fordi jeg har belæg for sådan en udtalelse, direkte
fra Bjarne Stroustrups udtalelser, og ikke blot fra foredraget på Vesterbro.
Der er ikke behov for at du gang på gang forsøger at korrigere mine udsagn,
med dine igen ufunderede opfattelser, som blot bidrager med forvirring og
misinformation.
Der er ikke nogen grund til at _gætte_ på at det er noget med:
for_each(buf, line_writer(fout))
Det kan du bare skrive i C++ idag som det er, hvis du syntes der er behov
for det.
Det kræver ikke en ny syntaks:
<code>
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <cstdlib>
template <typename C, typename F>
void for_each(const C& c, F f)
{
for(typename C::const_iterator i = c.begin(); c.end() != i; ++i) {
f(*i);
}
}
class line_writer
{
public:
line_writer(std::ostream& os) :
os_(os) {}
template <typename T>
void operator()(const T& t)
{ os_ << t << std::endl; }
private:
std::ostream& os_;
};
int main()
try {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
for_each(v, line_writer(std::cout));
std::set<std::string> s;
s.insert("Hello");
s.insert("World");
for_each(s, line_writer(std::cerr));
}
catch(...)
{
return EXIT_FAILURE;
}
</code>
Hvis man vil komme med troværdige udsagn om hvad Bjarne Stroustrup har i
tankerne, når han snakker om et mindre og pænere sprog (D&E, side 207) , må
man henvise til noget af hans arbejde - sådan som jeg gjorde (der er andre
kilder, f.eks. D&E, side 45).
Lyder det som noget der er blevet sagt tidligere i denne tråd ?
Alt andet må stå for andres regning - f.eks. når du siger "Bjarne Stroustrup
sagde engang... Det må så være et sprog, hvor...".
Det er gætværk, som på ingen måde kan henføres til Bjarne Stroustrup, sådan
som du gjorde.
Jeg kan forstå at du higer efter et eller andet punkt, hvor du kan korrigere
mine udtalelser - f.eks. ved forkert at påstå at man ikke kan debugge
Release udgaver.
Du ved måske ikke hvordan man styrer compiler/linker options i Microsoft
Visual C++ ?
I så fald kan du spørge på denne nyhedsgruppe - der er mange folk der kan
give gode, venligt formulerede, velfunderede og nyttige svar.
Jeg kan berolige dig med at det nok skal lykkes på et tidspunkt, at fange
mig i at sige noget forkert. Du kan endda få lov til at grine af det, hvis
du får det bedre på den måde.
Jeg har ikke noget problem med at blive korrigeret af folk med viden og
indsigt, men gentagne uigennemtænkte udsagn er der ikke grund til at have
respekt for.
Det er lidt trættende i længden at skulle gå at rydde op efter dig på denne
nyhedsgruppe.
Andre i denne nyhedsgruppe har formuleret tilsvarende synspunkt i mere
bastante vendinger.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (07-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 07-08-02 14:10 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aiqodi$2144$1@news.cybercity.dk...
> At du kommer hjem til Århus kun med det helt konkrete indhold af
foredraget
> er naturligvis forståeligt, men beklageligt.
Du læser noget ud af mit indlæg som ikke er der. Du har ikke den ringeste
ide om hvad jeg fik med hjem fra foredraget.
> Når jeg siger at man kan "se en flig af hvordan syntaksen måske kunne
være",
> så er det naturligvis fordi jeg har belæg for sådan en udtalelse, direkte
> fra Bjarne Stroustrups udtalelser, og ikke blot fra foredraget på
Vesterbro.
Så BS mener selv at hans XTI sprog til compileret typeinformation også ville
være et godt bud på en flig af det struggling language der findes oppe i
hans hoved?
Det kan jeg selvfølgelig ikke sige noget imod, højst undres.
> Der er ikke nogen grund til at _gætte_ på at det er noget med:
> for_each(buf, line_writer(fout))
> Det kan du bare skrive i C++ idag som det er, hvis du syntes der er behov
> for det.
> Det kræver ikke en ny syntaks:
Næ, det krævede åbenbart bare omkring 40 linier kode.
Iøvrigt er der et problem med den form for wrappere i nuværende C++. Hvis de
ikke konstrueres med et allerede eksisterende, navngivet objekt, vil de kun
fungere inde i det udtryk hvori de er skabt. Selvom dine 40 linier tillader
dig at formulere "for_each(buf, line_writer(fout))", så går det i stykker i
bare lidt mere komplicerede eksempler.
> Du ved måske ikke hvordan man styrer compiler/linker options i Microsoft
> Visual C++ ?
Jo.
Igen læser du noget ud af mit indlæg som ikke er der. Jeg står fast ved at
* Man kan ikke debugge nondebug-kode (medmindre man har lyst til at gøre
det på assembler-niveau, selvfølgelig).
* Det er ikke noget ukendt fænomen at have et program der fungerer i
Debug-udgave, men ikke i Release-udgave.
> Det er lidt trættende i længden at skulle gå at rydde op efter dig på
denne
> nyhedsgruppe.
Så vil jeg anbefale dig til at holde en pause og slappe lidt af.
Bjarke
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 15:15 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:30949.6577$G3.817158@news010.worldonline.dk...
[8<8<8<]
> Jeg står fast ved at
> * Man kan ikke debugge nondebug-kode (medmindre man har lyst til at gøre
> det på assembler-niveau, selvfølgelig).
> * Det er ikke noget ukendt fænomen at have et program der fungerer i
> Debug-udgave, men ikke i Release-udgave.
Stå du bare fast hvor du står - det siger _ingenting_ som kan bruges.
I sammenhæng er det er en ligegyldighed.
Man kan debugge Release-udgaven på source-niveau.
Det er interessant.
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (09-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 09-08-02 06:01 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:30949.6577$G3.817158@news010.worldonline.dk...
[8<8<8<]
> Næ, det krævede åbenbart bare omkring 40 linier kode.
Det er klart at du ikke kan være tilfreds med at få hvad du bad om.
> Iøvrigt er der et problem med den form for wrappere i nuværende C++. Hvis
de
> ikke konstrueres med et allerede eksisterende, navngivet objekt, vil de
kun
> fungere inde i det udtryk hvori de er skabt. Selvom dine 40 linier
tillader
> dig at formulere "for_each(buf, line_writer(fout))", så går det i stykker
i
> bare lidt mere komplicerede eksempler.
Måske Boost Lambda biblioteket
( http://www.boost.org/libs/lambda/doc/index.html) kan hjælpe dig ?
Så kan du f.eks. skrive
for_each(a.begin(), a.end(), std::cout << _1 << '\n');
Venlig hilsen
Mogens Hansen
| |
Anders J. Munch (06-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 06-08-02 22:25 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> skrev:
> Som jeg opfatter det mindre og pænerere sprog, drejer det sig primært om
at
> rydde op i syntaksen, forenkle steder hvor man kan gøre det samme på flere
> måder, gøre det simplere at komme igang.
>
> Hvis man vil se en flig af hvordan syntaksen måske kunne være, så side 22
af
> http://www.klid.dk/arrangementer/XTI_kbh.pdf
Nydeligt .. der mangler da vist nogle semikolonner til at afslutte
erklæringer, eller er han virkelig gået Python-vejen og har brugt
signifikant whitespace <g>? Jeg kan godt li' notationen. Den er måske lige
en anelse for minimal, det virker som om variabel- og type-erklæringer
bruger samme notation. Jeg har tænkt lidt i samme baner, men jeg ville
bevare typedef nøgleordet til at skelne med.
Bemærk at erklæringerne starter med <identifier> ":", hvilket gør dem
kompatible med dagens C++, da ingen sætninger eller erklæringer kan starte
sådan idag. Man kunne faktisk indføre denne notation sideordnet med den
gamle, og så udfase den klassiske notation over et årti eller to.
>
> Men stadig med mange af de samme egenskaber, f.eks.:
> * statisk typechecket
> * understøttelse af mange programmeringsstile samtidig
> * have et stort dynamikområde, der gør det mulighed for at skrive
> effektive programmer samtidig med højniveau konstruktioner
> * deterministisk objekt livstid
Lige netop objektlevetid er en ting jeg ville ønske at ændre, hvis det var
muligt (men altså ikke for at gøre den non-deterministisk). Den stærke
binding mellem objektlevetid og variabellevetid, som skaber behovet for
default-construction og den megen specielle syntaks omkring constructors,
ville jeg gerne fjerne. Sproget kunne være noget simplere hvis objekter ikke
blev konstrueret før første tildeling.
- Anders
| |
Jonas Meyer Rasmusse~ (06-08-2002)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 06-08-02 19:20 |
|
"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:LaG39.3764$G3.610087@news010.worldonline.dk...
> I en C++ advocacy artikel er hastighedssammenligninger relevante, og
> Bjarne har i parentes bemærket fuldstændigt ret i alt hvad han skriver
> om emnet. Men relevans for indlæring?
Bemærkede du at artiklen var skrevet til CUJ? Dette gør da en væsentlig
forskel, da de fleste læsere af dette blad har en vis forståelse for emnet.
For mig bliver det ihvertfald mere forståeligt, hvorfor han bringer den
sammenligning ind.
Jonas
| |
Anders J. Munch (06-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 06-08-02 22:25 |
|
"Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> skrev:
> "Anders J. Munch" <andersjm@inbound.dk> wrote:
> > I en C++ advocacy artikel er hastighedssammenligninger relevante, og
> > Bjarne har i parentes bemærket fuldstændigt ret i alt hvad han skriver
> > om emnet. Men relevans for indlæring?
>
> Bemærkede du at artiklen var skrevet til CUJ? Dette gør da en væsentlig
> forskel, da de fleste læsere af dette blad har en vis forståelse for
emnet.
> For mig bliver det ihvertfald mere forståeligt, hvorfor han bringer den
> sammenligning ind.
Ikke forstået. Den samme præmis fører mig til den modsatte konklusion. De
velinformerede CUJ læsere må formodes at vide i forvejen at velskrevet C++
er (mindst) lige så hurtigt som C, og det gør hastighedssammenligningen
*mere* malplaceret.
Men det skal man nu ikke lægge for meget i, hverken den ene eller den anden
vej. Artikler bliver ikke altid trykt i det forum, forfatteren havde i
tankerne da han skrev det.
- Anders
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 17:02 |
|
Unskyld det sene svar, men det krævede en del arbejde.
"Anders J. Munch" <andersjm@inbound.dk> wrote
> "Mogens Hansen" <mogens_h@dk-online.dk> skrev:
> >
> > "Anders J. Munch" <andersjm@inbound.dk> wrote:
> >
> > [8<8<8<]
>
> Det symbol kender jeg ikke?
Det er sakse - "her er der klippet".
Jeg kan ikke husker hvor jeg så det første gang.
[8<8<8<]
> Forresten tvivler jeg ikke på din erfaring -- hvad end du vælger for
> kodestil, så vil du givetvis kunne få det til at skalere godt til
> store programmer
Tak
[8<8<8<]
> Så gerne .. her følger et program uden unavngivne magiske tal, uden
> unødige casts, uden "0" brugt som hverken bogstav eller pointer, uden
> isspace bug'en, uden prematur optimering og en del kortere end
> Bjarnes.
Det er et interessant bud.
Magiske tal:
I Bjarne Stroustrups program kan jeg se:
1. "int max = 20"
2. "if(i == max-1)"
1. kan måske med lidt god vilje kalde et magisk tal, men jeg ser det blot
som en initial-værdi.
Magiske tal er for mig typisk konstanter, som man ikke ved hvor stammer fra:
char filename[72];
2. syntes jeg ikke rigtig er et magisk tal. Det er nærmest idiomatisk for 0
er index på første element.
De unødige cast:
Det er vist en gammel diskution mellem C og C++.
Kernigham og Pike diskuterer det lidt på side 43 i "The Practice of
Programming", men vælger at skrive med cast for så er det både gyldig C og
C++.
Bemærk iøvrigt at Bjarne Stroustrups program er C++ skrevet i C stil. C89
(som var gældende på det tidspunkt) tillader ikke erklæringen af "int i = 0"
midt i det hele.
I og med at det er et C++ program er castene nødvendige.
Det er trivielt at skrive det om til et rent C program.
Vi kan nok blive enige om at det er en detalje.
Brug af "0":
NULL <> er igen en gammel diskution mellem C og C++.
Der er igen tvivl om at Bjarne Stroustrup fortrække 0 frem for NULL, når der
testes på pointere.
Igen: det er et C++ program, skrevet i C stil.
Jeg foretrækker også '\0' frem for 0, når en streng skal nul-termineres.
Begge dele opfatter jeg som en lille detalje.
ispace bug'en er forbigået min opmærksomhed.
Kan du ikke lige skære det ud i pap for mig ?
[8<8<8< kode 8<8<8<]
OK.
Det er jo åbenlyst kortere.
Så vidt jeg kan se, er det også korrekt.
Dit program har i ligheder med Bjarne Stroustrups på side 2, og til forskel
fra programmet på side 3, ikke nogen separat fejlmelding ved en
out-of-memory situation. Det er helt i orden for mig, og simpelt at tilføje
til dit program, hvis måtte ønskes.
Jeg kan godt lide at du bruger "size_t" i stedet for "int" - det øger
portabiliteten.
Med hensyn til prematur optimering:
Jeg går ud fra at du mener den måde som Bjarne Stroustrup bruger realloc på,
hvor blokken fordobles i størrelse. Jeg opfatter den måde at gøre det på som
idiomatisk - men andre kan selvfølgelig have en anden opfattelse.
Man kan i forhold til dit program hævde at det er prematur optimering kun at
allokere netop den hukommelsesmængde der er nødvendig - det er ikke noget
jeg vil holde alt for hårdt fast på.
Jeg syntes at man kan kritesere din løsning for ikke at formidle et design,
der skalerer til større problemer. Hvis det ikke er et menneske, men en
computer som genererer data, så vil din løsning kunne påtrykke et anseeligt
performance overhead. Det er almindeligt at heap-manageren er forholdsvis
langsom, og det er almindeligt kendt at unødig kopiering (ved realloc) er
dyrt for servere.
Det er naturligvis værd at skrive korte programmer.
Men vis man unødigt optimerer på længden, mod at det bliver sværere at
vedligeholde, så er de også prematur optimering.
Dit program bidrager med en væsentlig kompleksitet, som Bjarne Stroustrups
ikke har.
Du har reelt 2 pointere: een til databufferen (name - burde måske hedde
buffer ?) og een til det faktiske data (resultatet af ltrim).
Bjarne Stroustrups program har _kun_ det data som man reelt er interesseret
i - muligvis i en buffer, der er lidt for stor.
Desuden skal man i hele dit program holde øje med om name er NULL.
Bjarne Stroustrups terminerer så snart realloc fejler.
Hovedparten af Bjarne Stroustrups program betår af to deles der kunne
splittes op i to funktioner (skip_ws og input_name - rundt regnet de to
while løkker).
Hver disse funktioner vil være veldesignet i forhold til klassiske kritier
som coupling og cohesion: de laver hver een ting, og gør det godt.
Dit program forekommer mig hårdere koblet.
Lad os nu forestilles os, den ikke helt urealistiske situation, at chefen
kommer og siger:
"Det er et rigtigt godt program du har lavet der.
Præcis som jeg havde sagt at jeg ønskede det, og det kører godt og stabilt.
Jeg han god nyhed: der er mere arbejde til dig.
Jeg har nemlig fundet ud af at vi har brug for 2 ekstra features:
1. Vi skal prikke til hans samvittighed, for at sikre os at det er hans
rigtige navn. Derfor skal programmet skrive "I guess ??? is your real name".
2. Vi skal ikke blot kunne sige velkommen til een, men til mange - lige
indtil vi skriver "quit"
Hvornår er du færdig ?"
Jeg får følgende programmer:
<Modificeret Bjarne Stroustrup C++ stil program>
#include <iostream>
#include <string>
int main()
{
using namespace std;
while(true) { /* added */
cout << "Please enter your first name:\n";
string name;
cin >> name;
if(name == "quit") return 0; /* added */
cout << "Hello " << name << '\n';
cout << "I guess your real name is " << name << '\n'; /* added */
} /* added */
}
<Modificeret Bjarne Stroustrup C++ stil program>
<Modificeret Bjarne Stroustrup C-stil program>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h> /*added*/
void quit()
{
fprintf(stderr, "memory exhausted\n");
exit(1);
}
int main()
{
int max = 20;
char* name = (char*) malloc(max);
if(name == 0) quit();
while(true) { /*added*/
printf("Please enter your first name:\n");
while(true) {
int c = getchar();
if(c == EOF) break;
if(!isspace(c)) {
ungetc(c, stdin);
break;
}
}
int i = 0;
while(true) {
int c = getchar();
if(c == '\n' || c == EOF) {
name[i] = 0;
break;
}
name[i] = c;
if(i == max-1) {
max = max+max;
name = (char*) realloc(name, max);
if(name == 0) quit();
}
i++;
}
if(!strcmp(name, "quit")) break; /*added*/
printf("Hello %s\n", name);
printf("I guess your real name is %s\n", name); /*added*/
} /*added*/
free(name);
return 0;
}
</Modificeret Bjarne Stroustrup C-stil program>
<Modificeret Anders J. Munch C program>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h> /*added*/
char const* ltrim(char const* s)
{
while(isspace((unsigned char)*s)) ++s;
return s;
}
int main()
{
int term = 0; /*added*/
do { /*added*/
char* buffer = NULL;
const char* name; /*added*/
size_t len = 0;
int c;
printf("Please enter your first name:\n");
while((c = getchar()) != EOF && c != '\n')
{
buffer = realloc(buffer, len+2);
if(buffer == NULL) break;
buffer[len++] = c;
buffer[len] = '\0';
}
name = buffer==NULL? "" : ltrim(buffer); /*added*/
if(buffer && strcmp("quit", name)) { /*added*/
printf("Hello %s\n", name);
printf("I guess your real name is %s\n", name); /*added*/
}
else
term = 1; /*added*/
free(buffer);
} while(!term); /*added*/
return 0;
}
</Modificeret Anders J. Munch C program>
Jeg håber at jeg har været nogenlunde fair mod alle eksemplerne - det var
min mening.
Jeg har løst det, som jeg ville gøre hvis jeg skulle vedligeholde de
respektive programmer.
Hvis ikke, så bare giv mig stokkeslag - og kom med et bedre bud
Det interessante er at se, hvordan de nødvendig ændringer i programmerne
svarer til ændringerne i krav-specifikationen.
C++ stil programmet syntes jeg mest præcist svarer til ændringerne i
kravene, men det "Modificerede Bjarne Stroustrup C-stil program" følger tæt
efter.
Det "Modificerede Anders J. Munch C program" kræver flere ændringer, fordi
det skinner igennem at der reelt er 2 pointere og fordi programmet ikke
terminerer så snart realloc fejler.
[8<8<8<]
> Men relevans for indlæring?
Troen på at højere niveau konstruktioner sikkert kører væsentligt
langsommere end C, er for nogen tilstrækkeligt til at afstå fra at begynde
at lære alternativer.
[8<8<8<]
> int main(int argc, char* argv[])
> {
> char* file = argv[2];
>
> Behøver jeg kommentere det?
uha-uha.
Venlig hilsen
Mogens Hansen
| |
Martin M. Pedersen (07-08-2002)
| Kommentar Fra : Martin M. Pedersen |
Dato : 07-08-02 20:04 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:airg0q$2tm3$1@news.cybercity.dk...
> Jeg foretrækker også '\0' frem for 0, når en streng skal nul-termineres.
0 har den fordel fremfor '\0', at 0 matcher typemæssigt med både char og
wchar_t. Derfor foretrækker jeg 0.
> ispace bug'en er forbigået min opmærksomhed.
> Kan du ikke lige skære det ud i pap for mig ?
isspace() er veldefineret for værdierne 0..255 samt EOF. Kaldt med en
negativ char, fx 'æ', 'ø' eller 'å' i ISO-8859, vil isspace() sandsynligvis
(afhængigt af implementationen) indeksere sig nedenud af sine interne
tabeller, hvilket igen kan medføre mere eller mindre tilfældige returværdier
eller at programmet vælter pga. access violation.
Derfor bør isspace() og vennerne i <ctype.h> altid benyttes med et cast til
unsigned char, dersom man står med en potentiel negativ char - præcis som
Anders gjorde i sit eksempel.
mvh.
Martin
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 19:44 |
|
"Martin M. Pedersen" <mmp@ www.moeller-pedersen.dk> wrote
> isspace() er veldefineret for værdierne 0..255 samt EOF. Kaldt med en
> negativ char, fx 'æ', 'ø' eller 'å' i ISO-8859, vil isspace()
sandsynligvis
> (afhængigt af implementationen) indeksere sig nedenud af sine interne
> tabeller, hvilket igen kan medføre mere eller mindre tilfældige
returværdier
> eller at programmet vælter pga. access violation.
Tak.
Det kan jeg godt se - det står der højt og flot i C standarden.
Er det ikke _fuldstændigt_ uforståelig ?
Hvorfor tager de så ikke bare "unsigned char" som argument i stedet for
int - så skulle den være fikset.
Sådan er det heldigvis ikke i C++ locale biblioteket.
Venlig hilsen
Mogens Hansen
| |
Martin M. Pedersen (07-08-2002)
| Kommentar Fra : Martin M. Pedersen |
Dato : 07-08-02 20:54 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:airpdl$859$1@news.cybercity.dk...
> > isspace() er veldefineret for værdierne 0..255 samt EOF.
> Hvorfor tager de så ikke bare "unsigned char" som argument i stedet for
> int - så skulle den være fikset.
Så ville de ikke kunne understøtte EOF. Det er vel historisk betinget
snarere end fordi det er praktisk. Det var sikkert praktisk for K&R
oprindeligt, der kunne nøjes med at spekulere over 7-bit ASCII.
mvh.
Martin
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 20:03 |
|
"Martin M. Pedersen" <mmp@ www.moeller-pedersen.dk> wrote
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote
> > ispace bug'en er forbigået min opmærksomhed.
> > Kan du ikke lige skære det ud i pap for mig ?
>
> isspace() er veldefineret for værdierne 0..255 samt EOF. Kaldt med en
> negativ char, fx 'æ', 'ø' eller 'å' i ISO-8859, vil isspace()
sandsynligvis
> (afhængigt af implementationen) indeksere sig nedenud af sine interne
> tabeller, hvilket igen kan medføre mere eller mindre tilfældige
returværdier
> eller at programmet vælter pga. access violation.
>
> Derfor bør isspace() og vennerne i <ctype.h> altid benyttes med et cast
til
> unsigned char, dersom man står med en potentiel negativ char - præcis som
> Anders gjorde i sit eksempel.
Der er ikke tale om fejl i Bjarne Stroustrups program.
Det har under ingen omstændigheder "undefined behaviour" som følge af brugen
af "isspace".
"getchar" er garanteret til at et tegn som "unsigned char" konverteret til
int, og opfylder derfor betingelserne for at kalde "isspace".
Se beskrivelen af "fgetc", hvor "getchar" ifølge standarden ender.
Venlig hilsen
Mogens Hansen
| |
Martin M. Pedersen (07-08-2002)
| Kommentar Fra : Martin M. Pedersen |
Dato : 07-08-02 21:52 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:airqii$a6b$1@news.cybercity.dk...
> Der er ikke tale om fejl i Bjarne Stroustrups program.
> Det har under ingen omstændigheder "undefined behaviour" som følge af
brugen
> af "isspace".
Du har ret. Jeg havde ikke set Bjarne Stroustrups program (dengang), men
blot set Anders' hvor det var nødvendigt med en cast.
mvh.
Martin
| |
Anders J. Munch (10-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 10-08-02 18:31 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:airqii$a6b$1@news.cybercity.dk...
> "Martin M. Pedersen" <mmp@ www.moeller-pedersen.dk> wrote
> > Derfor bør isspace() og vennerne i <ctype.h> altid benyttes med et cast
> til
> > unsigned char, dersom man står med en potentiel negativ char - præcis
som
> > Anders gjorde i sit eksempel.
>
> Der er ikke tale om fejl i Bjarne Stroustrups program.
> Det har under ingen omstændigheder "undefined behaviour" som følge af
brugen
> af "isspace".
Min fejl, der er ikke nogen bug.
Men det kommer der! Første omfaktorering, hvor tegnet bliver lagret eller
overført i en char, så dukker den op. Et cast til unsigned char er altid en
god idé med is*.
- Anders
| |
Anders J. Munch (10-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 10-08-02 19:36 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:airg0q$2tm3$1@news.cybercity.dk...
> Unskyld det sene svar, men det krævede en del arbejde.
Ikke noget problem - se bare hvor lang tid det tog for mig. Mine
usenet-vaner blev formet dengang leveringstiderne for e-post og
papirs-post var sammenlignelige.
Jeg har skrevet et laaangt svar til Bjarne, så holder jeg til gengæld
det her kort.
Jeg er ikke enig i at mit C-stil program skalerer dårligere.
Pseudokode for det modificerede program:
loop:
name = læs en linie fra input
if name == "quit":
break loop
print "Hello " name
Dit C++-program er bygget op med denne struktur. Din modifikation af
mit C-program er bygget op med denne struktur, blot er "break"
omformuleret til et flag aht. oprydning af allokeret lager.
Men din modifikation af Bjarnes program bryder strukturen! Bufferen
'name', som er logisk lokal for én løkkeiteration, erklærer og
vedligeholder du i det omgivende scope. Det er et smart træk på kort
sigt, for det sparer flaget. Men det er et hack.
>Dit program forekommer mig hårdere koblet.
Mit program er MINDRE koblet end Bjarnes. Det var bl.a. den kobling
mellem brugerinteraktion og forarbejdning der var i Bjarnes program,
der fik til at kritisere hans program til at begynde med. Se i øvrigt
mit svar på hans indlæg.
mvh.
Anders
| |
Mogens Hansen (11-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 11-08-02 09:32 |
|
"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:N4d59.8981$G3.1343159@news010.worldonline.dk...
[8<8<8<]
> Men din modifikation af Bjarnes program bryder strukturen! Bufferen
> 'name', som er logisk lokal for én løkkeiteration, erklærer og
> vedligeholder du i det omgivende scope. Det er et smart træk på kort
> sigt, for det sparer flaget. Men det er et hack.
Jeg forstår hvad du mener.
Men kortsigt og hack syntes jeg ikke det er.
Jeg kiggede på stilen i alle programmerne, og prøvede at fortsætte den.
Bjarne Stroustrup C-stil programmet brugte eksponentiel allokering, hvilket
jeg tolker som "allokering er relativ dyr". Derfor mente jeg at det var
naturligt at genbruge hukommelsen fra det ene gennemløb til det næste.
Jeg var faktisk i gang med at tilføje flaget, men det gav den ydre
while-løkke en anden stil end de 2 indre while-løkker, samt en if-sætning
omkring udskriften. Det virkede uharmonisk.
Så fik jeg øje på løsningen med break, og syntes det passede fint med
programmets øvrige struktur.
> >Dit program forekommer mig hårdere koblet.
>
> Mit program er MINDRE koblet end Bjarnes. Det var bl.a. den kobling
> mellem brugerinteraktion og forarbejdning der var i Bjarnes program,
> der fik til at kritisere hans program til at begynde med. Se i øvrigt
> mit svar på hans indlæg.
Jeg syntes netop at dit program har en kobling mellem brugerinteraktionen og
forarbejdningen.
Dit program har ikke de egentlige data direkte - kun via ltrim.
Hvis dit program efter input havde haft:
name = strdup(ltrim(buffer)); // [1]
free(buffer);
if(!name) quit();
så havde koblingen mellem brugerinteraktion og forarbejdning ikke været der.
Vurderingen af kobling afhænger nok af øjnene som ser.
Venlig hilsen
Mogens Hansen
[1]
Jeg ved godt at strdup ikke er en standard funktion, men den er nem at lave:
char* strdup(const char* text)
{
if(!text) return 0;
char* dup = (char*) malloc(strlen(text)+1);
if(dup)
strcpy(dup, text);
return dup;
}
| |
Anders J. Munch (11-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 11-08-02 13:02 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> skrev:
>
> Bjarne Stroustrup C-stil programmet brugte eksponentiel allokering,
hvilket
> jeg tolker som "allokering er relativ dyr". Derfor mente jeg at det var
> naturligt at genbruge hukommelsen fra det ene gennemløb til det næste.
Ingen af C++-stil programmerne har denne optimering, så hvorfor er det
pludseligt nødvendigt i C?
Har du i øvrigt lagt mærke til, at C++-stil-programmerne er O(n^2)?
std::string behøver jo ikke bruge eksponentiel allokering, og der er
implementationer der ikke gør det.
>
> Vurderingen af kobling afhænger nok af øjnene som ser.
Lad os bare sige det og standse program-dissekeringen her.
mvh. Anders
| |
Bjarne Stroustrup (07-08-2002)
| Kommentar Fra : Bjarne Stroustrup |
Dato : 07-08-02 20:28 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> skrev:
>
> "Anders J. Munch" <andersjm@inbound.dk> wrote:
>
> [8<8<8<]
Det symbol kender jeg ikke?
> > I new_learning.pdf falder han i vandet: Artiklen handler ikke ret
> > meget om indlÂ?ring men meget om at vise hvor meget lettere
> > smÂ?programmer er at skrive i C++ end i C.
Nej. Det er ca. 500 boeger der forsoeger at laere folk C++ og
*mange* goer det paa en maade der efter min mening goer det
unoedvaerdigt svaert for laerne at forstaa C++ begreber og i
min erfaring skraemmer folk fra nogle af det mest effektive
C++ teknikker. Med "effektive" mener jeg "programs to be easy
to write, correct, maintainable, and acceptably efficient"
(fra artiklens foerste saetning). Ofte er C++ kurser (der jo
ofte bruger boeger) heller ikke bedre.
Min artikel "Learning Standard C++ as a New Language"
http://www.research.att.com/~bs/new_learning.pdf
blev skrevet efter at "The C/C++ Users Journal"s "Senior Editor"
Chuck Allison bad mig om en artikel om mine meninger om og
erfaringer med C++ undervisning. Det er en artikel om hvordan
*mange* begynder et C++ kursus og om hvordan man kan goere det
bedre. Alt i artiklen har med programmeringsstil og
undervisningsstil at goere. Hovedtemaerne er blant dem man ofte
hoerer i diskussioner om undervisning.
Artiklen er ikke - som nogen har haevdet - en programmeringssprogs
sammenligning. Havde den vaeret det ville den jo havde vaeret
haabloest smalsporet - den naevner jo slet ikke de fleste
sprogelementer, grundprincipper, eller teknikker. Jeg skriver
ikke sprog sammenligninger. For en forklaring hvorfor ikke,
see "The Design and Evolution of C++" eller min FAQ.
> Min _erfaring_ er at de overvejelser Bjarne Stroustrup gÂ?r i artiklen,
netop
> ogsÂ? skalerer godt til _store_ programmer.
> MÂ?den som folk bliver undervist pÂ? fra starten spiller en stor rolle for
> hvordan de programmerer senere.
Enig. Jeg ser det som samme tankegang der ligger bag, nÂ?r Eric Raymond
skriver: "LISP is worth learning for a different reason --- the
profound enlightenment experience you will have when you finally get
it. That experience will make you a better programmer [...]"[1]
Jeg tror derimod ikke pÂ? at
copy(buf.begin(),buf.end(),ostream_iterator<string>(fout, '\n'))
vil gÂ?re nogen til en bedre programmÂ?r, hvis de ikke i forvejen har
fanget pointen, fx da de lÂ?rte et funktionsprogrammeringssprog. Det er
for tungt at danse med til at en begynder vil kunne vÂ?rdsÂ?tte
fordelene.
Jeg har ofte brugt saadanne programmer til at begynde laere
folk at vaerdsaette generic programmering (or de ideer fra
functional programming som generic programming delvist er
bygget paa). Se f.eks. Kapitel 3 af "The C++ Programming Language".
Men her er copy() blot brugt i kode som jeg skrev fordi
en af mine kollegaer haevedede at mine eksempler i en tidligere
(unpublished) version ikke var realistiske: Han ville ikke tro
paa at teknikkerne var rimeligt effektive for files med strings
saavel som for files med floating-points. Der var/er i oevrigt
en typisk reaktion - isaer fra gamle C programmoerer ("hvis det
er kort og elegant, saa maa det vaere for langtsomt").
Det eksempel er ikke et af dem jeg ville vise studenter i den
foerste eller anden time af et C++ kursus - og naar jeg foerst
viser den teknik forklarer jeg ikke alle deltaljer.
Det er et eksempel der viser at teknikkerne virker for problemer
der er mere realistiske end dem man starter med. Her i AT&T
Labs har vi brugt saadanne smaa programmer til at analysere
multi-gigabyte data streams. Bemaerk at et a mine hovedpunkter
i den artiklen er at det ikke er en god ide at laere folk
noget der er elegant; men ikke kan bruges i realistiske programmer.
Forresten tvivler jeg ikke pÂ? din erfaring -- hvad end du vÂ?lger for
kodestil, sÂ? vil du givetvis kunne fÂ? det til at skalere godt til
store programmer
>
> > Med tydelig bias: Opgaverne
> > er skrÂ?ddersyet til C++,
Opgaverne var ikke skraeddersyede, de var eksempler paa hvad man kan finde
i C++ boeger for begyndere. Det er naermere at C++ er skraeddersyet til
den slags problemer - og mange andre.
> > hans C-kode er elendig (programmet side 3 kan
> > stort set skrives pÂ? den halve plads),
>
> Det er vel ikke sÂ?dan at du vil poste din udgave af hans C-program fra
side
> 3 ?
> Det er forbigÂ?et min opmÂ?rksomhed at det kan gÂ?res vÂ?sentligt bedre.
SÂ? gerne .. her fÂ?lger et program uden unavngivne magiske tal, uden
unÂ?dige casts, uden "0" brugt som hverken bogstav eller pointer, uden
isspace bug'en, uden prematur optimering og en del kortere end
Bjarnes.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
char const* ltrim(char const* s)
{
while(isspace((unsigned char)*s)) ++s;
return s;
}
int main()
{
char* name = NULL;
size_t len = 0;
int c;
printf("Please enter your first name:\n");
while((c = getchar()) != EOF && c != '\n')
{
name = realloc(name, len+2);
if(name == NULL) break;
name[len++] = c;
name[len] = '\0';
}
printf("Hello %s\n", name==NULL? "" : ltrim(name));
free(name);
}
>
Det er bestemt et mindre program
[day] wc p1 p2
26 69 522 p1
47 137 893 p2
men det er gjort ved at fjerne den specifikke fejlmeddelelse,
ved ikke at retunere en success/failure indikator, ved at bruge
en mere elegant og mindre effektiv allokerings strategi, og ved at
bruge den ekstra ltrim() funktion. Dereduver er mit program C++
og det er alternativet ikke: resultatet fra realloc() er en void*
som i C++ ikke kan implicit konverteres til en char*.
Jeg har intet imod 0 som pointer or character - det er kun et
problem naar man har et svagere type system, og artiklen var
on C++ undervisning.
Jeg skrev min version som jeg skrev den fordi jeg ville vise
hvordan det originale "simple traditional C-style" program
#include<stdio.h> // get standard I/O facilities
int main()
{
const int max = 20; // maximum name length is 19 characters
char name[max];
printf("Please enter your first name:\en");
scanf("%s",name); // read characters into name
printf("Hello %s\en",name);
return 0;
}
som man ofte ser i begynder literatur typisk er forbedret - ikke
hvordan dette specifikke problem bedst kan loeses. Jeg tror ikke
at jeg er unfair og de teknikker jeg bruger i det eksempel bruger
jeg jo igen i denaeste smaaprogrammer.
"to solve the original simple problem, I had to introduce loops,
tests, storage sizes, pointers, casts, and explicit free-store
management in addition to whatever a solution to the problem
inherently needs." Den alternative loesning er kortere; men
bruger ca. de samme begreber. Derudover intrudusere den "assignment
in test" and "unsigner char".
Jeg er ikke i tvivl om hvilken loesning (C++ stil vs. C stil) er
den laetteste at forklare til nybegyndere - ellere laettere at
finde fejl i i et stoerre program. Jeg er heller ikke i tvivl
om hvilken C-style loesning er mest karakteristisk for studenter
og instruktoer kode.
> > han foretager irrelevante
> > hastighedssammenligninger,
>
> Hastighedssammenligninger er ikke irrelevante.
> Det er en almindelig bekymring i forhold til C++, hvis man kommer fra en C
> baggrund.
I en C++ advocacy artikel er hastighedssammenligninger relevante, og
Bjarne har i parentes bemÂ?rket fuldstÂ?ndigt ret i alt hvad han skriver
om emnet. Men relevans for indlÂ?ring?
Som jeg sagde er artiklen om undervisning/indlaering og
programmeringsstil - ikke en "language advocacy" artikel.
Et af de mest debaterede undervisningsspoersmaal er om man
kan/skal ignorere "effektivitet/performance". Der er mange der
haevder at effiktivitet er irrelevant ("today, we have infinite
cycles and infinite bandwidth" er en eksakt citat fra et foredrag
jeg hoerte i sidste uge). Der er mange der haevder at man bestemt
skal ignorere effektivitet i begyndelsen og kun vise studenterne
de mest elegante faciliteter, teknikker, og sprog. Problemet
ved det er at folk der kun kender saadanne faciliteter ofte
har svaert ved at skrive real-world programmer med akseptabel
effektivitet. Derfor, maa man ikke blot vise at noget er elegant;
man maa ogsaa vise at det kan bruges udenfor et skolelokale.
Som jeg siger i artiklen:
"Why do I discuss efficiency in the context of programming style
and teaching? The styles and techniques we teach must scale to
real-world problems. C++ is - among other things - intended for
large-scale systems and systems with efficiency constraints.
Consequently, I consider it unacceptable to teach C++ in a way
that leads people to use styles and techniques that are effective
for toy programs only; that would lead people to failure and to
abandon what was taught."
Det er ogsaa et faktum at C++ programmer der bruger standard
library faciliteter saa som string, vector, or algorithms ofte
bliver kritiseret for at vaere "too inefficient". I en klasse
er der *altid* en eller flere der simpelt her er uvillige til
at tro paa at noget der er rimeligt "high-level" ogsaa kan koere
hurtigt. Ofte, folk med den holdning er gamle C eller C-stil-C++
programmoerer. Min erfaring er at det er noedvaendigt at
demonstrere run-time efficiency af de grundlaekkene biblioteks
faciliteter - ellers knomplikere folk deres kode for at undgaa
"inefficiencies" uden foerst at maale hvad der koster hvad.
Vaerre endnu, laerere og laerebogsforfattere goer det samme.
F.eks. hvis jeg havde brugt Anderses program isteadet for mit
"elendige" eksempel ville jeg vaere blevet kaldt "inconsistent"
og "unfair" fordi det har et "unoedvaendige" funktions kald og
en subobtimal allokeringsstrategi. Det ville vaere en unfair
kritik; men det ville alligevel tage tid at svare.
Bemaerk at jeg har en god ide om hvordan folk reagere om emnerne
i den artikel. Jeg har presenteret versioner af "Learning Standard
C++ as a New Language" mange gange og svaret paa dusinvis af
spoergsmaal efter hvert foredrag, artiklen er blevet downloaded
fra mine hjemmesider mere end 100 gange om dagen (i gennemsnit)
over de sidste tre aar og jeg har modtaget langt over hundrede
emails om den, og der har vaeret mange net discussions om den,
og jeg har siddet paa paneler om "C++ undervisning". Artiklen
var skrevet efter aars erfaring med disse emner.
>
> > han kritiserer sit strÂ?mands-C-program for
> > at mangle fejlcheck men overser de (vigtigere!) fejlcheck der mangler
> > ogsÂ? i hans C++-programmer.
De var begge C++ programmer. Jeg diskutere stil - ikke sprog.
Hvis mit maal havde vaeret at demostraere fejl ved C ville jeg
have givet andre eksempler.
> Hvilke fejlcheck er det, der mangler i hans C++ programmer ?
> Man kan selvfÂ?lgelig sige, at pÂ? side 2 burde der fanges en bad_alloc
> exception og udskrives en fejlmelding, hvis de skal svare til programmet
pÂ?
> side 3. Men programmet opfÂ?rer sig pÂ?nt og veldefineret i tilfÂ?lde af
fejl.
Typisk start pÂ? main i artiklens programmer:
int main(int argc, char* argv[])
{
char* file = argv[2];
BehÂ?ver jeg kommentere det?
Jeg tror du nok maa kommentere mere hvis du oensker en loedig
diskussion. Jeg skulle selvfoelgelig have tested hvormange argumenter
der kom; men paa den anden side er det ikke godt at drukne den
kritiske kode i kode der egentlig kun er en del af mit test harnis.
Koden som jeg postede paa mine hjemmesider har lidt mere kode
der kun bruges til at hjaelpe tests; men jeg checker ikke for
"wrong number of arguments" - jeg koerte den kode fra et script.
Jeg vil tilfoeje et test. Tak.
Grunden til at jeg brugte files isteadet for standard input er
at det for begyndere der bruger Windows er det ikke let at pipe
en file ind i standard input.
- Anders
[1] http://www.tuxedo.org/~esr/faqs/hacker-howto.html
- Bjarne
Bjarne Stroustrup - http://www.research.att.com/~bs
| |
Bent G. A. Stigsen (08-08-2002)
| Kommentar Fra : Bent G. A. Stigsen |
Dato : 08-08-02 00:09 |
|
On Wed, 07 Aug 2002 21:27:43 +0200, Bjarne Stroustrup wrote:
[snip]
jadajadajadajada
[snip]
> - Bjarne
>
> Bjarne Stroustrup - http://www.research.att.com/~bs
Selvom du forsvarer hans synspunkt, er det ikke pænt, at misbruge
andres identitet.
| |
Mogens Hansen (08-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 08-08-02 04:29 |
|
"Bent G. A. Stigsen" <nospam.ng@thevoid.dk> wrote
> [snip]
> > - Bjarne
> >
> > Bjarne Stroustrup - http://www.research.att.com/~bs
>
> Selvom du forsvarer hans synspunkt, er det ikke pænt, at misbruge
> andres identitet.
Jeg går naturligvis ud fra at det er mig du hentyder til.
Bjarne Stroustrups identitet er _ikke_ misbrugt i forbindelse med
overstående indlæg.
Det er godt at du stiller spørgsmålet, når du er i tvivl om ægtheden.
Man skal ikke tage let på at misbruge andres indentitet.
Personligt kunne jeg aldrig drømme om det.
Jeg står naturligvis ved mine indlæg, og poster derfor altid under korrekt
og eget navn.
Det er korrekt at hans indlæg er postet fra min maskine. Men det _er_ Bjarne
Stroustrups indlæg.
Jeg ændrede naturligvis opsætningen af min account, så man hurtigt kan se at
det var et indlæg fra Bjarne Stroustup - og ikke blot endnu et fra mig.
Bjarne Stroustrup sendte på eget initiativ indlægget, med følgende
forklaring:
<citat>
Mogensm
Jeg fandt denne artikel (og den thread den var del af) paa google groups.
Desvaerre faar vi ikke dk.edb.programmering.c paa AT&T's maskiner saa jeg
kan ikke svare direkte (naar jeg har proevet at poste via google groups er
der altid nogen der tvivler paa at det virkelig er mig).
Vi du vaere venlig at poste dette svar for mig?
</citat>
For god orden skyld skal det samtidig siges at jeg ikke på noget tidspunkt,
i forbindelse med denne tråd, har taget initiativ til personlig
kommunikation med Bjarne Stroustrup.
Han er _ikke_ blevet opmærksom på tråden efter hint fra mig.
Hvis han søger på sig eget navn på google, for at se hvad han bliver
"beskyldt" for verden over og sorterer efter dato, så vil han givetvis finde
denne tråd.
Hans indlæg er på _ingen_ måde plantet af mig - det vil formodentlig end
ikke kunne lade sig gøre.
Prøv at læs Bjarne Stroustrups indlæg igennem endnu en gang. Se på udsagnene
og formuleringerne, og vurder om det lyder sandsynligt at det er ægte.
Bemærk at hans indlæg ikke kommenterer eller støtter nogen af mine udsagn i
tråden.
Det er ikke underligt at Bjarne Stroustrup sendte sin mail til mig:
Dels står min e-mail adresse mange gange i tråden.
Dels har Bjarne Stroustrup og undertegnede kendt hinanden personligt gennem
efterhånden nogen år.
Jeg forwarder gerne den fulde mail til enhver der er interesseret - med en
opfordring til at svare på gruppen her hvorvidt de tror på ægtheden.
(For god ordens skyld, skal jeg sige at Bjarke Dahl Ebert har sendt mig en
privat mail, hvor han forståeligt spørger til ægtheden. Han har naturligvis
fået samme forklaring, samt jeg har forwardet Bjarne Stroustrups mail, og
bedt han udtrykke sit indtryk af ægtheden på gruppen. Når han poster sit
svar er det altså ikke et udtryk for at han ikke tror på dette indlæg - han
har ikke haft mulighed for at læse det).
Der står ikke andet i Bjarne Stroustrups private mail til mig end hans
indlæg som det er postet på gruppen og ovennævnte forklaring på hvorfor han
beder mig poste.
Jeg håber ikke at der er nogen der har grund til at drage ovenstående i
tvivl.
I modsat fald, så sig frem.
Venlig hilsen
Mogens Hansen
| |
Ivan Johansen (08-08-2002)
| Kommentar Fra : Ivan Johansen |
Dato : 08-08-02 07:52 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message >
> Bjarne Stroustrup sendte på eget initiativ indlægget, med følgende
> forklaring:
> <citat>
> Mogensm
>
> Jeg fandt denne artikel (og den thread den var del af) paa google groups.
> Desvaerre faar vi ikke dk.edb.programmering.c paa AT&T's maskiner saa jeg
> kan ikke svare direkte (naar jeg har proevet at poste via google groups er
> der altid nogen der tvivler paa at det virkelig er mig).
>
> Vi du vaere venlig at poste dette svar for mig?
> </citat>
Jeg vil bare gøre opmærksom på at man kan få en gratis usenet konto på
sunsite.dk. Se http://sunsite.dk/info/usenet.xml for detaljer.
Ivan Johansen
| |
Bjarke Dahl Ebert (08-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 08-08-02 08:17 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aiso8u$18me$1@news.cybercity.dk...
Tak for den udførlige forklaring, Mogens.
> "Bent G. A. Stigsen" <nospam.ng@thevoid.dk> wrote
> > Selvom du forsvarer hans synspunkt, er det ikke pænt, at misbruge
> > andres identitet.
[...]
> Prøv at læs Bjarne Stroustrups indlæg igennem endnu en gang. Se på
udsagnene
> og formuleringerne, og vurder om det lyder sandsynligt at det er ægte.
Jeg tvivler ikke et sekund på at det er Bjarne Stroustrup.
Det er tydeligt at det er Bjarne Stroustrups formuleringer og at det er hans
indsigt der ligger bag.
> (For god ordens skyld, skal jeg sige at Bjarke Dahl Ebert har sendt mig en
> privat mail, hvor han forståeligt spørger til ægtheden. Han har
naturligvis
Lad mig lige sige at jeg i bemeldte email gættede på at det *var* Bjarne
Stroustrup, men fysisk postet fra Mogens Hansens account. Jeg bad blot
Mogens for god ordens skyld forklare den rette sammenhæng, sådan at der ikke
bliver anledning til at betvivle ægtheden.
For at undgå misforståelser og ubegrundede beskyldninger, ville det nok have
været bedre fra starten at poste under eget navn og forklare at man var
blevet bedt om at poste dette indlæg.
Mvh. Bjarke
| |
Mogens Hansen (08-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 08-08-02 16:45 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
[8<8<8<]
> Lad mig lige sige at jeg i bemeldte email gættede på at det *var* Bjarne
> Stroustrup, men fysisk postet fra Mogens Hansens account.
Fuldstændigt korrekt.
Der var ikke skyggen af uhøflighed, beskyldning eller mistænkeliggørelse i
Bjarke Dahl Eberts mail.
> Jeg bad blot
> Mogens for god ordens skyld forklare den rette sammenhæng, sådan at der
ikke
> bliver anledning til at betvivle ægtheden.
Hvilket jeg finder fuldstændigt velbegrundet.
> For at undgå misforståelser og ubegrundede beskyldninger, ville det nok
have
> været bedre fra starten at poste under eget navn og forklare at man var
> blevet bedt om at poste dette indlæg.
Jeg var naturligvis ikke forberedt på en sådan mail fra Bjarne Stroustrup.
Jeg overvejede kort muligheden for at skrive "Jeg er blevet bedt om at poste
følgende for Bjarne Stroustrup:", inden jeg postede.
Det ville have betydet 3 ting:
1. Indlægget ville starte med mine forklaringer - hvilket er støj.
2. Mit navn ville stå som afsender, og indlægget kunne således forbigå en
række personers opmærksomhed.
3. Det ville ikke give større sikkerhed for at det ikke var det pure
opspind fra min side.
Venlig hilsen
Mogens Hansen
| |
Byrial Jensen (10-08-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 10-08-02 10:41 |
|
Bjarke Dahl Ebert <bebert@worldonline.dk> skrev:
> For at undgå misforståelser og ubegrundede beskyldninger, ville det nok
> have været bedre fra starten at poste under eget navn og forklare at man
> var blevet bedt om at poste dette indlæg.
Det var korrekt - som Mogens gjorde - at skrive det rigtige
forfatternavn i "From:"-feltet.
Men når den fysiske afsender er forskellig fra den egentlige
forfatter, burde Mogens have tilføjet et "Sender:"-felt med sit
egen navn og e-post-adresse. Situationen er beskrevet i RFC 1036
om Usenet-indlæg.
| |
Bent G. A. Stigsen (08-08-2002)
| Kommentar Fra : Bent G. A. Stigsen |
Dato : 08-08-02 17:30 |
|
On Thu, 08 Aug 2002 05:29:24 +0200, Mogens Hansen wrote:
> "Bent G. A. Stigsen" <nospam.ng@thevoid.dk> wrote
>
>> [snip]
>> > - Bjarne
>> >
>> > Bjarne Stroustrup - http://www.research.att.com/~bs
>>
>> Selvom du forsvarer hans synspunkt, er det ikke pænt, at misbruge andres
>> identitet.
[snip]
> Bjarne Stroustrups identitet er _ikke_ misbrugt i forbindelse med
> overstående indlæg.
> Det er godt at du stiller spørgsmålet, når du er i tvivl om ægtheden.
Jeg vil gerne officielt undskylde til Mogens for min lidt hurtige beskyldning.
Jeg sendte en mail til Bjarne Stroustrup, og han kunne bekræfte at han havde
bedt Mogens om, at poste indlægget for ham.
Så indlægget er i dets helhed fra Bjarne Stroustrup.
mvh
Bent
--
Note to self: spørg før du skyder
| |
Mogens Hansen (08-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 08-08-02 17:20 |
|
"Bent G. A. Stigsen" <nospam.ng@thevoid.dk> wrote
> Jeg vil gerne officielt undskylde til Mogens for min lidt hurtige
beskyldning.
Det er i orden.
Lidt sund skepsis skal der til.
> Jeg sendte en mail til Bjarne Stroustrup, og han kunne bekræfte at han
havde
> bedt Mogens om, at poste indlægget for ham.
Tak for at du viderebringer det.
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (08-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 08-08-02 05:59 |
|
"Bent G. A. Stigsen" <nospam.ng@thevoid.dk> wrote
> Selvom du forsvarer hans synspunkt, er det ikke pænt, at misbruge
> andres identitet.
Som kuriosum kan jeg huske at den modsatte tvivl også har været rejst her på
gruppen; altså er Mogens Hansen et pseudonym som Bjarne Stroustrup bruger på
denne gruppe
Se evt.
http://groups.google.com/groups?hl=da&lr=&ie=UTF-8&oe=UTF-8&c2coff=1&selm=9d
gqk6%24gai%241%40news.inet.tele.dk
Venlig hilsen
Mogens Hansen
| |
Anders J. Munch (10-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 10-08-02 18:17 |
|
"Bjarne Stroustrup" <bs@research.att.com> skrev (citeret i anden
rækkefølge end skrevet):
Hej Bjarne,
Beklager det tog så længe at svare, men jeg har haft så travlt med et
bruge det glimrende sprog, du har skabt, at det ikke kunne blive før.
> Jeg skrev min version som jeg skrev den fordi jeg ville vise
> hvordan det originale "simple traditional C-style" program
Var det ikke scanf-versionen der var simple traditional versionen? Om
programmet s. 3 skriver du: "Most equivalent C and C++ programmers
would -- in a real program -- (hopefully?) have written something
equivalent in the first place."
Hvis formålet med artiklen er at finde den bedste måde at lære C++ på,
så er det jo ikke interessant hvordan C _typisk_ læres. Det er den
*bedste* måde at lære C++ startende med en C delmængde, der skal
sammenlignes med den *bedste* måde at lære C++ startende med
programmer baseret på højniveau-biblioteksfunktioner.
Personligt er jeg uafklaret på hvad der er den bedste måde at
undervise C++. På den ene side mener jeg det er en fordel at begynde
med et mere afgrænset kernesprog, som fx den delmængde der er fælles
med C. På den anden side er det lidt spild af tid at undervise i de
dele af C-biblioteket, som man ikke har brug for i C++.
Det virker som om at du associerer udviklingen af en mere struktureret
programmeringsstil med udviklingen de faciliteter i C++, der er skabt
for at understøtte den bedre stil.
For mig er det lidt både-og: Jeg er ikke i tvivl om at det har
forbedret min C programmeringsstil at bruge C++. Når jeg nu om dage en
gang imellem er nødt til at skrive C, så bruger jeg i høj grad
objekt-baseret programmering og "opremsnings-polymorfi" à la
stdio/FILE.
En eksempel på objekt-baseret programmering i C kunne være denne
ADT for at udfaktorere allokeringsstrategien fra vores eksempel:
typedef struct { ... } tegnbuffer;
extern void tegnbuffer_init(tegnbuffer*);
extern void tegnbuffer_nulstil(tegnbuffer*);
extern void tegnbuffer_frigiv(tegnbuffer*);
extern void tegnbuffer_append_tegn(tegnbuffer*, char);
extern char const tegnbuffer_c_str(tegnbuffer*);
Bemærk ligheden med:
class tegnbuffer
{
public:
tegnbuffer();
~tegnbuffer();
void append_tegn(char);
void nulstil();
char const* c_str() const;
};
Det er meget muligt, at dette ikke er typisk C, og det var det i hvert
fald ikke for 20 år siden, da C var dominerende. Men muligheden er til
stede for at programmere således, hvilket jeg gør i udpræget grad når
jeg er nødt til at bruge C, og muligheden er til stede for at
undervise C i den stil.
Hvis først man har set og skrevet objektbaseret kode i C, så er
springet til C++-klasser kort.
Jeg skrev ikke mit program på denne måde, dels fordi jeg ville have
det mere sammenligneligt med dit programs een-lang-main stil, og dels
så ville en mere modulariseret C-version måske snarere lægge
abstraktionssnittet et andet sted, med en udfaktoreret funktion til at
læse én input-linie à la:
char* input_linie(char const* prompt); /* kaldende skal deallokere */
---
Jeg ser strukturen af et simpelt input-output program sådan her:
1) Foretag I/O, læs ind i brugerens format.
2) Konverter brugerens format til en intern repræsentation, der er
velegnet til datamanipulation.
3) Foretag datamanipulation/beregninger.
4) Konverter beregningsresultat fra internt format til brugerens
format.
5) Foretag I/O, skriv ud i brugerens format.
Den logiske adskillelse mellem brugerens format og den interne
datastruktur ser jeg som vigtig; hvis man ikke har den adskillelse, og
lader sine interne datastrukturer i for høj grad afspejle hvor man har
fået data fra, så risikerer man torsionsproblemer mellem punkt 1, 3 og
5.
I det her tilfælde er programmet så simpelt at der ikke noget punkt 3
og 4. I mit program i while-løkken punkt 1, ltrim er punkt 2, og
printf er punkt 5. Brugerens format består af en linie tekst med
whitespace og det hele, og i det interne format er indledende
whitespace fjernet.
I dit program er punkt 1 og 2 blandet sammen, og det er derfor der er
to getchar-løkker. Hvis man fx forestiller sig at getchar bliver
erstattet med ubufferet tegninput, og man ønsker at ^H defineres til
at slette det sidst indtastede tegn, så bryder strukturen med to
getchar-løkker sammen.
> Bemaerk at et a mine hovedpunkter i den artiklen er at det ikke er en
> god ide at laere folk noget der er elegant; men ikke kan bruges i
> realistiske programmer.
Jeg ser ikke nogen modsætning. Elegante programmer er lettere at
omfaktorere, og omfaktorerbarhed er en livsnødvendig egenskab ved
realistiske programmer.
For eksempel skal det da være min mindste kunst at tilføje
eksponentiel allokering til mit program. Det kræver kun to linier i
main og en fem-liniers hjælpefunktion.
> Et af de mest debaterede undervisningsspoersmaal er om man kan/skal
> ignorere "effektivitet/performance". Der er mange der haevder at
> effiktivitet er irrelevant ("today, we have infinite cycles and
> infinite bandwidth" er en eksakt citat fra et foredrag jeg hoerte i
> sidste uge).
LOL - fint så kan vi endelig få løst standsningsproblemet - med
inifinite cycles er det jo nemt nok
Det med at computere er blevet så hurtige at man kan/bør skifte til
langsommere programmeringssprog, det har man sagt de sidste 30 år,
mindst. Hver gang det bliver sagt demonstrerer det først og fremmest
talerens manglende fremsyn, men samtidigt er der også lidt sandhed i
det, for balancen forskubber sig hele tiden lidt. Jeg returnerer ofte
en std::string by value, selv om jeg ved at det er ineffektivt, men
det er hurtigt nok og holder koden enkel. Det havde jeg ikke gjort for
10 år siden.
> > Med tydelig bias: Opgaverne
> > er skrÂ?ddersyet til C++,
> Opgaverne var ikke skraeddersyede, de var eksempler paa hvad man kan
> finde i C++ boeger for begyndere. Det er naermere at C++ er
> skraeddersyet til den slags problemer - og mange andre.
For mig står std::sort som et af paradeeksemplerne (sammen med
std::map) på hvad C++ kan gøre bedre end C, kendetegnet ved at være et
template med kompleks implementation og simpel grænseflade. Det er
naturligt at bruge std::sort tidligt i et C++ undervisningsforløb.
Det er derimod ikke naturligt at bruge qsort lige så tidligt i et C
undervisningsforløb -- den kommer snarere som noget af det sidste man
lærer, som et eksempel på brug af funktionspointere.
Den anden ting der virker skræddersyet til C++ er afgrænsningen af
input i vores eksempelprogram. Den for mig at se naturlige
specifikation af problemet er: Læs en linie af input og fjern
whitespace først og sidst (eller for at være konsistent med den opgave
som programmet s. 3 løser, nøjes med at fjerne indledende
whitespace). Programmet øverst side 2 gør ingen af delene, men
forlader sig på hvad operator<< tilfældigvis gør for std::string. Prøv
med input "Jens Peter".
> >Typisk start pÂ? main i artiklens programmer:
> >
> >int main(int argc, char* argv[])
> >{
> > char* file = argv[2];
> >BehÂ?ver jeg kommentere det?
> Jeg tror du nok maa kommentere mere hvis du oensker en loedig
> diskussion. Jeg skulle selvfoelgelig have tested hvormange argumenter
> der kom; men paa den anden side er det ikke godt at drukne den
> kritiske kode i kode der egentlig kun er en del af mit test harnis.
Jeg har fuld forståelse for at pladsen er begrænset i en artikel. Det
er bare påfaldende i en artikel der netop diskuterer fejlhåndtering i
C-stils-kode. For at citere en klog mand:
"It can be argued that this kind of shoddiness is harmless as long as
the proper solution is presented 'later on'. However, [...] Ideally,
a novice user isn't presented with a program that brittle."
> Koden som jeg postede paa mine hjemmesider har lidt mere kode der kun
> bruges til at hjaelpe tests; men jeg checker ikke for "wrong number of
> arguments" - jeg koerte den kode fra et script. Jeg vil tilfoeje et
> test. Tak.
Fint, er du også opmærksom på at checke at åbning af filer lykkes?
> Det er bestemt et mindre program
>
> [day] wc p1 p2
> 26 69 522 p1
> 47 137 893 p2
>
> men det er gjort ved at fjerne den specifikke fejlmeddelelse,
> ved ikke at retunere en success/failure indikator, ved at bruge
> en mere elegant og mindre effektiv allokerings strategi, og ved at
> bruge den ekstra ltrim() funktion. Dereduver er mit program C++
> og det er alternativet ikke: resultatet fra realloc() er en void*
> som i C++ ikke kan implicit konverteres til en char*.
Ok, jeg tilføjer fejlmeddelelsen, tilføjer fejlreturns, tilføjer cast
så det bliver C++ og tilføjer - under YAGNI protest - eksponentiel
allokering. Resultat:
44 102 779 new_learning_s3_3.cpp
Surprise, surprise: Det er stadigt kortere! Og det på trods af at jeg
nu har to genanvendelige funktioner, ltrim og opalloker. Jeg kan da
godt inline dem så der ikke er nogen "ekstra ltrim funktion", men det
gør det jo kun kortere:
35 86 664 new_learning_s3_4.cpp
Det er selvfølgelig ikke størrelsen det kommer an på, men i det her
tilfælde skyldes forskellen den dobbelte getchar-løkke, og den er et
problem.
En sidste subtilitet: Begge vores C-stils programmer har en
hukommelsesoverløb-sårbarhed pga. muligheden for overløb i den
variabel der holder antal allokerede bytes. I mit program vil realloc
som regel fejle før det sker, da jeg bruger size_t. På platforme med
sizeof(int)<sizeof(size_t) er det et realistisk problem for dit
program. I øvrigt endnu et point til C++-versionen, som ikke har det
problem, forudsat std::string er korrekt implementeret.
mvh.
Anders
new_learning_s3_3.cpp
=====================
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
char const* ltrim(char const* s)
{
while(isspace((unsigned char)*s)) ++s;
return s;
}
void quit()
{
fprintf(stderr,"Memory exhausted");
exit(1);
}
void opalloker(char** s, size_t* str, size_t min)
{
while(*str < min)
{
*str = *str*2+1;
*s = (char*)realloc(*s, *str);
if(*s == NULL) quit();
}
}
int main()
{
char* name = NULL;
size_t len = 0;
size_t allok = 0;
int c;
printf("Please enter your first name:\n");
while((c = getchar()) != EOF && c != '\n')
{
opalloker(&name, &allok, len+2);
name[len++] = c;
name[len] = '\0';
}
if(name != NULL)
printf("Hello %s\n", ltrim(name));
free(name);
return 0;
}
| |
Per Abrahamsen (05-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 05-08-02 16:57 |
|
"Anders J. Munch" <andersjm@inbound.dk> writes:
> Jeg tænker for eksempel på reglerne for iterator invalidering.
Behøver man at lære dem? Det har jeg aldrig gjort, det naturlige er
at når man indsætter eller fjerner elementer er iteratoren ikke
længere gyldig. Sådan bruger jeg iteratorer i alle sprog.
> Jeg synes Bjarkes påstande er generelt fornuftige, og jeg synes du er
> unødigt grov her.
Jeg synes også han generelt argumenterer fornuftigt i
dk.edb.programmering, men at mit svar på den helt konkrete svinestreg
jeg kommeterede var overordentlig mild.
> Hvilken anden gruppe vil du da foreslå til at diskutere C og C++´s
> relative meritter?
Hvis det skal være som Bjarne gjorde i det eksempel jeg pointerede?
En gruppe der har "advocacy" eller "religion" i navnet.
Hvis det skal være en seriøs diskussion af C og C++ i forhold til
generelt sprogdesign, dk.edb.programmering.
| |
Bjarke Dahl Ebert (05-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 05-08-02 19:42 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
news:rjk7n5mh8d.fsf@zuse.dina.kvl.dk...
> "Anders J. Munch" <andersjm@inbound.dk> writes:
>
> > Jeg tænker for eksempel på reglerne for iterator invalidering.
> Behøver man at lære dem? Det har jeg aldrig gjort, det naturlige er
> at når man indsætter eller fjerner elementer er iteratoren ikke
> længere gyldig. Sådan bruger jeg iteratorer i alle sprog.
Men "ikke gyldig" betyder at hvis man ved en fejltagelse kommer til at bruge
den alligevel, så er resultatet "undefined behaviour" og for en
implementation gælder "no diagnostics required".
Standarden definerer i sagens natur ikke hvad "undefined behaviour" er, men
i stort set alle implementationer betyder det en af følgende tre ting:
(1) der sker ikke noget ved det
(2) man kommer til at overskrive noget hukommelse ejet af en anden struktur,
med vilkårligt mærkværdig opførsel til følge
(3) Access Violation.
Det er blandt andet dette, jeg mener med at man har lavniveau slået til hele
tiden. Man kan ikke vælge at se bort fra det - man er ikke "beskyttet" af en
særlig stærk abstraktion.
Bjarke (det *hedder* jeg altså
| |
Anders J. Munch (06-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 06-08-02 03:26 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> skrev:
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote:
> > > Jeg tænker for eksempel på reglerne for iterator invalidering.
> > Behøver man at lære dem? Det har jeg aldrig gjort, det naturlige er
> > at når man indsætter eller fjerner elementer er iteratoren ikke
> > længere gyldig. Sådan bruger jeg iteratorer i alle sprog.
>
> Men "ikke gyldig" betyder at hvis man ved en fejltagelse kommer til at
bruge
> den alligevel, så er resultatet "undefined behaviour" og for en
> implementation gælder "no diagnostics required".
> Standarden definerer i sagens natur ikke hvad "undefined behaviour" er,
men
> i stort set alle implementationer betyder det en af følgende tre ting:
> (1) der sker ikke noget ved det
> (2) man kommer til at overskrive noget hukommelse ejet af en anden
struktur,
> med vilkårligt mærkværdig opførsel til følge
> (3) Access Violation.
(4) Man bruger et debug-bibliotek med iterator-validering, og får en nydelig
fejlmelding.
Alt undefined behaviour i C++ kan detekteres, hvis man er parat til at
betale prisen.
- Anders
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 14:52 |
|
"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:vxG39.3766$G3.611580@news010.worldonline.dk...
> (4) Man bruger et debug-bibliotek med iterator-validering, og får en
nydelig
> fejlmelding.
Nåja, det vidste jeg egentlig også godt .
STLport har fx denne glimrende feature.
> Alt undefined behaviour i C++ kan detekteres, hvis man er parat til at
> betale prisen.
Ja, men det er kun en lille del af de mulige "undefined behaviours" der kan
checkes i libraries (som fx STLport).
Resten kræver support af compileren eller et tredieparts-værktøj (der typisk
instrumenterer koden før eller efter compilering).
Det er også fint nok at sådanne værktøjer findes, men jeg forstår simpelthen
ikke hvorfor compilere ikke generelt kommer med det som en
compiletime-option (MSVC og gcc gør fx ikke). Hvor svært kan det være? Det
må da være compileren det er nemmest for. Den har allerede parset koden, og
den har al nødvendig information tilgængelig. Et pre- eller
postprocesseringstool har det meget sværere.
Bjarke
| |
Mogens Hansen (06-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 06-08-02 20:06 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> Det er også fint nok at sådanne værktøjer findes, men jeg forstår
simpelthen
> ikke hvorfor compilere ikke generelt kommer med det som en
> compiletime-option (MSVC og gcc gør fx ikke). Hvor svært kan det være?
Jeg har gentagne gange i denne tråd, og mange tidligere, opfordret til at
bruge sådanne værktøjer, og peget på hvor man kan finde dem.
Borland C++ har haft det siden 1994.
Det viser sig, ikke overraskende, når jeg sammenligner Borland CodeGuard med
Rational Purify eller Valgrind at CodeGuard har en stor fordel ved at kende
source koden, især i relation til data der ikke ligger på heapen.
Sidst jeg talte med een af udviklerne på Microsoft Visual C++ efterlyste jeg
netop den slags funktionalitet.
NuMega BoundsChecker's instrumenteringsdel giver netop den slags
funktionalitet sammen med Visual C++ V6.0. NuMega's compiler går ind og
erstatter Microsofts. Det er så vidt jeg har forstået lavet i samarbejde med
Microsoft - den tilføjer "blot" instrumenteringen.
Venlig hilsen
Mogens Hansen
| |
Anders J. Munch (06-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 06-08-02 03:02 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> skrev:
> "Anders J. Munch" <andersjm@inbound.dk> writes:
>
> > Jeg tænker for eksempel på reglerne for iterator invalidering.
>
> Behøver man at lære dem? Det har jeg aldrig gjort, det naturlige er
> at når man indsætter eller fjerner elementer er iteratoren ikke
> længere gyldig. Sådan bruger jeg iteratorer i alle sprog.
Sandt nok, det kan man komme langt med. I Python, hvor jeg ikke kender
reglerne, gør jeg det samme. Nu da jeg alligevel kender reglerne i C++,
benytter jeg mig af det en gang imellem. Man kan også få brug for at kende
reglerne når man læser andre folks kode.
>
> > Jeg synes Bjarkes påstande er generelt fornuftige, og jeg synes du er
> > unødigt grov her.
>
> Jeg synes også han generelt argumenterer fornuftigt i
> dk.edb.programmering, men at mit svar på den helt konkrete svinestreg
> jeg kommeterede var overordentlig mild.
Da jeg ikke er interesseret i at føre citatkrig vil jeg nøjes med at sige at
jeg står ved mit udsagn.
- Anders
| |
Per Abrahamsen (05-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 05-08-02 17:04 |
|
igorr@ifi.uio.no (Igor V. Rafienko) writes:
> "ni"?
"We are the knights that say ecky ecky ecky ecky pi'ang zoop boing."
Bjarne er bare bagude.
| |
Per Abrahamsen (05-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 05-08-02 17:07 |
|
"Jonas Meyer Rasmussen" <meyer@remove.diku.this.dk> writes:
> Iøvrigt, hvis man skal forklare C++ nedefra og op, hvorfor skal C så
> ikke forklares nedefra og op?... og hvis du skal forklare C nedefra
> og op, skal du så egentlig ikke starte med en gennemgang af hvordan
> en computer virker, og hvorfor?
Tjah, der er faktisk en skole der siger at man skal lære assembler før
man lærer højniveausprog (FORTRAN er et højniveausprog i den
sammenhæng).
Og så er der dem der siger maskinkode før assembler, og gate logic før
maskinkode, og halvlederfysik før gate logic. Men de fleste af dem er
gået på pension nu.
| |
Per Abrahamsen (05-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 05-08-02 17:35 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> Men lavniveau er "slået til" hele tiden i C++, på godt og ondt. Man har ikke
> garbage-collection, der er ingen automatiske runtimechecks (kun dem man selv
> laver), dvs. specielt ingen arraybound-checking, check af at en reference
> stadig peger på et gyldigt objekt, check af at objektet faktisk har den type
> som pointervariablen er kvalificeret med, osv.
Ovenstående features afhænger af implementationen.
Hvis din pointe er at en implementation med ovenstående slået til vil
være mere velegnet til en begynder end en implementation hvos
ovenstående ikke er slået til, vil du få svært ved at finde folk fra
nogen af skolerne der er uenige.
De er da også komplet uafhængige af "niveau", det er alene et
spørgsmål om check for fejl på runtime (bortset fra garbage
collection). Alle overnstående fejl kan optræde i højniveau og
lavniveau kode, i alle generelle sprog.
> Så i C++ kan man ikke bare glemme lavniveau'et, heller ikke når man benytter
> højniveau-konstruktioner.
Hvilket dermed bliver til en non sequitor.
> Bottom-Up skolen mener derimod at det bliver for sent. For at forklare hvad
> "std::string mystr;" er, må man sige at det reserverer et stykke hukommelse
> med navnet "mystr" og tillægger det streng-type. Desuden forsvinder dette
> stykke hukommelse automatisk når man forlader scope, hvilket specielt
> betyder at man ikke længere kan bruge det erklærede navn "mystr".
Så nested scope er lavniveauprogrammering?
Så er det måske bedre hvis folk direkte kaster sig ud i højniveausprog
som BASIC hvos man ikke risikerer at et navn går ud af scope.
> Og hvis
> man kalder en funktion f(string&), så kan f referere til dette stykke
> hukommelse (og ændre det), ikke bare til værdien af strengen.
Du har allerede tabt mig, så jeg tror ikke din teknik er den bedste
for begyndere.
> Hvad siger I - giver det nogen mening?
Nej.
Det eneste jeg har kunne hive ud af hvad du skriver er at runtime
check er en god ting i en omgivelse rettet mod indlæring af
programmering, hvilket vi er rørende enige om.
> Nu kender jeg jo desværre ikke "Accelerated C++",
Jeg har heller ikke læst den.
> Måske har jeg ikke forstået dit spørgsmål rigtigt? Skær det gerne ud i pap
> for mig
Lad mig prøve:
Der er en skole, lad os kalde den pro-Python, der mener at Python er
et godt programmeringssprog for begyndere.
Og så er der en anden skole, lad os kalde den pro-runtime-check, der
derimod mener at runtime check er nyttige når begyndere skal lære at
programmere.
Nu vil forklare hvorfor jeg tilhører pro-runtime-check skolen, og ikke
pro-Python skolen. Runtime cheks er gode fordi...
Synes du ovenstående er en ærlig måde at svare på et spørgsmål fra en
Python begynder?
| |
Bjarke Dahl Ebert (05-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 05-08-02 20:21 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
news:rjy9bll0vu.fsf@zuse.dina.kvl.dk...
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
>
> > Men lavniveau er "slået til" hele tiden i C++, på godt og ondt. Man har
ikke
> > garbage-collection, der er ingen automatiske runtimechecks (kun dem man
selv
> > laver), dvs. specielt ingen arraybound-checking, check af at en
reference
> > stadig peger på et gyldigt objekt, check af at objektet faktisk har den
type
> > som pointervariablen er kvalificeret med, osv.
>
> Ovenstående features afhænger af implementationen.
Ja, men stort set alle implementationer har det som beskrevet af ovenstående
features. Standarden forlanger derfor selvfølgelig heller ikke disse
features, og at bero på dem ville binde en til en bestemt implementation.
> De er da også komplet uafhængige af "niveau", det er alene et
> spørgsmål om check for fejl på runtime (bortset fra garbage
Jeg opfatter snarere de nævnte features som nogle ting der kan få
højniveauet abstraheret mere væk fra lavniveauet.
> collection). Alle overnstående fejl kan optræde i højniveau og
> lavniveau kode, i alle generelle sprog.
Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et destrueret
objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
eller null.
Den store forskel er "undefined behaviour". I de fleste andre sprog har man
højst "unspecified", dvs. standarden giver en vis frihed til
implementationer, men blot ikke frihed til at crashe.
Jeg siger ikke at jeg ønsker at standarden kræver "defineret opførsel" af
alle operationer i C++. Der er jo en grund til at implementationer ikke kan
garantere dette, og det er performance. Hvis hver pointer skulle checkes,
ville C++ være et helt anderledes sprog, der ikke ville egne sig til
system-level programmering.
Til opgaver hvor jeg eksplicit *ikke* ønsker disse checks (fordi de er for
dyre og fordi den givne compiler-implementationen ville diktere
memorylayoutet i højere grad end nu), så mener jeg da også at C++ er langt
det bedste sprog.
> > Bottom-Up skolen mener derimod at det bliver for sent. For at forklare
hvad
> > "std::string mystr;" er, må man sige at det reserverer et stykke
hukommelse
> > med navnet "mystr" og tillægger det streng-type. Desuden forsvinder
dette
> > stykke hukommelse automatisk når man forlader scope, hvilket specielt
> > betyder at man ikke længere kan bruge det erklærede navn "mystr".
>
> Så nested scope er lavniveauprogrammering?
Nej, std::string og nested scope henregner jeg til højniveau-fænomener.
Det jeg siger er at der i C++'s måde at håndtere disse højniveauting på
skinner ting igennem der hører lavniveau til. Fx kan man i C++ stadig kigge
på den plads hvor strengen engang lå, men den vil være væk, og der vil evt.
ligge noget andet. Man tvinges til at tænke i "hukommelsespladser (bytes)
der kan indeholde skiftende objekter" snarere end at koncentrere sig om
"objekter i et scope", som man kan i fx Scheme, der er ægte højniveau. Man
skal *selv* huske at "den adresse må vi ikke bruge mere, for den plads er
lejet ud til en anden som vi ikke har fået invitation af", præcis som man
skal i C og assembler, men ikke ret mange andre sprog. Bruger man den
alligevel, får man i *bedste* fald en protection fault, i *værste* fald sker
der ingenting (kun ude hos kunden).
Så kald det runtime-check, men checks (i det hele taget - runtimecheck er
bare en måde at få det på) er efter min mening det der skal til, før man kan
sige at man har ordentlig adskillelse mellem højniveau og lavniveau.
Sammenlign det evt. med memory-protection mellem forskellige processer. Det
er den adskillelse der skal til, for at man kan tale om sådanne
abstraktioner som at "en proces har sit eget adresserum". Enhver abstraktion
må vel involvere noget maskineri til at sikre at man virkelig holder sig
abstrakt og ikke ser de detaljer man abstraherer væk fra (undtagen, måske,
når man eksplicit beder om det)
Kun sådan kan man efter min mening få "rigtig" højniveau.
Hvis højniveau er gearstang og speeder, så er man med C++ nede i
maskinrummet og kan godt betjene disse ting, men man kan også se tandhjulene
dreje, og kaste grus i maskineriet.
Jeg siger ikke at man ikke kan nøjes med at betjene gaskabel og gearkabel,
men det er sundt at være bekendt med tandhjulene lige fra starten, så man
ikke laver ulykker.
Mvh. Bjarke
| |
Mogens Hansen (05-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-08-02 21:04 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote
>
> > "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> >
[8<8<8<]
> Ja, men stort set alle implementationer har det som beskrevet af
ovenstående
> features. Standarden forlanger derfor selvfølgelig heller ikke disse
> features, og at bero på dem ville binde en til en bestemt implementation.
Forkert.
Man binder sig ikke til nogen bestemt implementation ved at bruge værktøjer
som:
* Borland CodeGuard (Borland C++Builder)
* Numega BoundsChecker (Visual C++)
* Rational (Visual C++, Intel C++, Unix)
* Valgrind (Linux på x86)
idet ingen af de værktøjer kræver nogen form for ændringer i koden.
Man har naturligvis kun deres funktionalitet til rådighed, når man bruger
dem - men det er noget andet.
[8<8<8<]
> Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et destrueret
> objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
> eller null.
Forkert.
Man kan godt have en reference i Java til et destrueret objekt (hvor
Finalize er kald) .
Har du nogensinde hørt om resurrection i Java og C# ?
Derudover kan man nemt have referencer til objekter, der logisk set er
nedlagt, hvorved programmerne kan få fejlagtig opførsel.
Hvis jeg har et bogholderiprogram, der holder en reference til en faktura
der allerede er betalt, vil det give et forkert svar hvis det skal beregne
hvor mange penge jeg har til gode.
Jeg er egentlig ligeglad med om et program crasher eller giver forkert svar.
Det skal virke korrekt uanset hvad.
I det miljø hvor jeg færdes, hvor fejl kan have deciderede fatale følger, er
et forkert svar ikke acceptabelt.
_Ingen_ vil have forståelse hvis jeg siger "jamen - det crashede jo ikke
!???"
Venlig hilsen
Mogens Hansen
| |
Ulrik Magnusson (05-08-2002)
| Kommentar Fra : Ulrik Magnusson |
Dato : 05-08-02 22:17 |
|
Mogens Hansen wrote:
> [8<8<8<]
> > Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et destrueret
> > objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
> > eller null.
> Forkert.
> Man kan godt have en reference i Java til et destrueret objekt (hvor
> Finalize er kald) .
Bare det at finalize() er kaldt betyder vel ikke at objektet er
destrueret? Det betyder vel bare at finalize koden er blevet
udført .
> Har du nogensinde hørt om resurrection i Java og C# ?
Det er vel netop her man ser at objektet ikke er destrueret bare
fordi finalize() er blevet kaldt? finalize() er jo ikke en destructor.
(jeg har i øvrigt ikke brugt finalize() i flere år netop pga dens
fjollede "måske-måske ikke" semantik..)
Ulrik Magnusson
| |
Mogens Hansen (05-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-08-02 22:52 |
|
"Ulrik Magnusson" <ulrikm@yahoo.com> wrote in message
news:3D4EEB4A.191C796D@yahoo.com...
[]8<8<8<]
> Bare det at finalize() er kaldt betyder vel ikke at objektet er
> destrueret? Det betyder vel bare at finalize koden er blevet
> udført .
Se mit svar til Mads Andersen.
[8<8<8<]
> (jeg har i øvrigt ikke brugt finalize() i flere år netop pga dens
> fjollede "måske-måske ikke" semantik..)
Naturligvis ikke.
Det normalt ikke anbefalet at bruge finalize af flere grunde.
Venlig hilsen
Mogens Hansen
| |
Mads Andersen (05-08-2002)
| Kommentar Fra : Mads Andersen |
Dato : 05-08-02 22:26 |
|
> > Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et
> > destrueret objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som
> > underklasse) eller null.
>
> Forkert.
> Man kan godt have en reference i Java til et destrueret objekt (hvor
> Finalize er kald) .
> Har du nogensinde hørt om resurrection i Java og C# ?
Der er jo ikke tale om et destrueret objekt i Java bare fordi finalize er
kaldt. finalize() metoden er *ikke* en destruktor! finalize skal mere
opfattes som en "hook", som bliver kaldt første gang et objekt er parat til
at blive nedlagt af garbage collector'en (dette sker ikke nødvendigvis i
samme øjeblik dette er muligt, men når gc algoritmen har lyst). Objektet
ligger stadig i hukommelsen, tilgang er lovlig efter resurrection osv. Hvis
ikke tilgang af objektet efter resurrection med en af XReference klasserne
var lovligt og velovervejet, tror du så XReference klasserne fandtes?
> Derudover kan man nemt have referencer til objekter, der logisk set er
> nedlagt, hvorved programmerne kan få fejlagtig opførsel.
Hvis objektet logisk set er nedlagt kan man jo ikke have referencer til det?
Det er da i selvmodsigelse...
Mvh. Madsie
| |
Mogens Hansen (05-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-08-02 22:53 |
|
"Mads Andersen" <madsie@mail.dk> wrote
[8<8<8<]
> Der er jo ikke tale om et destrueret objekt i Java bare fordi finalize er
> kaldt. finalize() metoden er *ikke* en destruktor!
Nej, finalize er ikke en destructor.
Men efter resurrection kan man have en objektgraf, hvor halvdelen af
objekterne har fået kaldt finalize og den anden halvdel ikke har.
Hvis finalize skal have nogen som helst praktisk betydning (hvad den ikke
har), så et den tilstand noget rod, som er moralsk ækvivalent med en
dangling pointer i C og C++.
Tilstanden vil være udefineret, idet man ikke kan basere sig på hvilke
objekter der har fået kaldt finalize og hvilke der ikke har.
[8<8<8<]
> Hvis objektet logisk set er nedlagt kan man jo ikke have referencer til
det?
> Det er da i selvmodsigelse...
Overhovedet ikke.
Hvis fakturaen er betalt, men hele applikationen ikke er enig med sig selv
om det pga. en programmeringsfejl, så er det logisk set (i forhold til
problem domainet) nedlagt, men kan ikke fysisk garbage collectes.
Venlig hilsen
Mogens Hansen
| |
Mads Andersen (05-08-2002)
| Kommentar Fra : Mads Andersen |
Dato : 05-08-02 23:34 |
|
> > Der er jo ikke tale om et destrueret objekt i Java bare fordi finalize
> > er kaldt. finalize() metoden er *ikke* en destruktor!
>
> Nej, finalize er ikke en destructor.
> Men efter resurrection kan man have en objektgraf, hvor halvdelen af
> objekterne har fået kaldt finalize og den anden halvdel ikke har.
> Hvis finalize skal have nogen som helst praktisk betydning (hvad den ikke
> har), så et den tilstand noget rod, som er moralsk ækvivalent med en
> dangling pointer i C og C++.
Bortset fra at referencen stadig peger på det samme objekt som VM'en stadig
anerkender som det samme objekt, og ikke ud i intetheden, men deri ligger
måske det "moralsk ækvivalente"
> Tilstanden vil være udefineret, idet man ikke kan basere sig på hvilke
> objekter der har fået kaldt finalize og hvilke der ikke har.
Det gør de fleste klasser i fx AWT biblioteket. De dispose'r deres native
peers i deres finalize metoder, men gendanner dem igen hvis et objekt igen
tages i brug.
> > Hvis objektet logisk set er nedlagt kan man jo ikke have referencer til
> > det?
> > Det er da i selvmodsigelse...
>
> Overhovedet ikke.
Kommer lidt an på hvad man ligger i "logisk set", jeg så på det teoretisk.
Her vil jeg mene at så længe man gar referencer til et objekt er det ikke
nedlagt
> Hvis fakturaen er betalt, men hele applikationen ikke er enig med sig selv
> om det pga. en programmeringsfejl, så er det logisk set (i forhold til
> problem domainet) nedlagt, men kan ikke fysisk garbage collectes.
Jeg forstår ikke hvordan noget programmeringssprog kan sikres mod logiske
programmeringsfejl af den art?
Derimod sætter brugerne af mit system (i Java) pris på, at det"aldrig"
crash'er[1], fx ved en uheldig plug-in. En operation kan mislykkes, men det
påvirker ikke systemets overordnede kørsel. Dermed mister brugerne sjældent
deres data.
[1] har endnu ikke nogen beskyttelse mod uendelige loops.
Mvh. Madsie
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 01:01 |
|
"Mads Andersen" <madsie@mail.dk> wrote in message news:aimu96
> Derimod sætter brugerne af mit system (i Java) pris på, at det"aldrig"
> crash'er[1], fx ved en uheldig plug-in.
> [1] har endnu ikke nogen beskyttelse mod uendelige loops.
Har Java ikke engang løst Halting-problemet?? Skuffende.
;)
Bjarke
| |
Mads Andersen (06-08-2002)
| Kommentar Fra : Mads Andersen |
Dato : 06-08-02 02:21 |
|
> > Derimod sætter brugerne af mit system (i Java) pris på, at det"aldrig"
> > crash'er[1], fx ved en uheldig plug-in.
>
> > [1] har endnu ikke nogen beskyttelse mod uendelige loops.
>
> Har Java ikke engang løst Halting-problemet?? Skuffende.
Haha... Har dog hørt Microsoft har lovet at C# skulle have denne
funktionalitet
Men mere seriøst... hvad jeg mente var nu noget simplere. Nemlig blot at
lade en plug-in operation starte i sin egen tråd. Hvis ikke operationen er
kommet til ende efter x tid, skal en requester dukke op og spørge om man vil
dræbe den. Lidt a la hvad fx Windows gør.
Mvh. Madsie
| |
Ulrik Magnusson (06-08-2002)
| Kommentar Fra : Ulrik Magnusson |
Dato : 06-08-02 00:18 |
|
Mogens Hansen wrote:
> Nej, finalize er ikke en destructor.
> Men efter resurrection kan man have en objektgraf, hvor halvdelen af
> objekterne har fået kaldt finalize og den anden halvdel ikke har.
> Hvis finalize skal have nogen som helst praktisk betydning (hvad den ikke
> har), så et den tilstand noget rod, som er moralsk ækvivalent med en
> dangling pointer i C og C++.
Jeg synes nu stadig denne sammenligning er noget grov. Man kan sige at
det er en fejl at resurrection kan finde sted, men det medfører ikke at
objekter ødelægges i egentlig forstand - kun at deres associerede
elementer sættes til null eller fortsætter med at eksistere (de 2 tilstande
som Bjarke oprindeligt diskede op med). Men ok, "moralsk ækvivalent"
kan vi da godt kalde det.
Ulrik Magnusson
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 01:07 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aimrrd$sqo$2@news.cybercity.dk...
> Hvis fakturaen er betalt, men hele applikationen ikke er enig med sig selv
> om det pga. en programmeringsfejl, så er det logisk set (i forhold til
> problem domainet) nedlagt, men kan ikke fysisk garbage collectes.
Det er rigtigt at man sagtens kan have memory leaks i et garbage-collected
sprog.
Garbage-collectoren har jo nødvendigvis en ret primitiv mening om hvilke
data der "kan nås".
Så selvom et objekt er "glemt" af et program (dvs. aldrig mere tilgås), så
kan garbage-collectoren ikke se dette, så man kan godt sige at logisk set er
objektet dødt.
Dette kan der ikke gøres noget ved (det er uafgørligt (i Turing-forstand) om
et objekt kan nås).
Denne situation er i de fleste situationer bedre end pointer der peger ud i
den blå luft.
Bjarke
| |
Esben Mose Hansen (09-08-2002)
| Kommentar Fra : Esben Mose Hansen |
Dato : 09-08-02 23:18 |
|
Bjarke Dahl Ebert wrote:
> Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et destrueret
> objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
> eller null.
<grin> virkeligt? Watch me!
class A {
public A { initialize(); }
protected void initilize() { }
}
class B extends A {
public Foo foo;
public B { super(); }
public void initialize() { // overriding A..
// foo peger på u-initialiseret memory
// idet kun A er constructed...
foo = new Foo();
}
}
//main
B b = new B; //crash
"Tricket" er at forbryde sig mod at kalde non-final metoder i en
constructor :) Det er nemmere i C++, men det bider hårdere i Java :D
(Jeg kan ikke huske om det er sådan at man kalder superkonstrutoren i
Java.. et område jeg først /rigtigt/ fattede da jeg lærte C++. )
Og nej. Jeg har ikke noget mod Java, og bruger det da selv, omend ikke
så meget længere.
--
mvh. Esben
home.worldonline.dk/~mesben
| |
Mogens Hansen (10-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 10-08-02 05:43 |
|
"Esben Mose Hansen" <esben@SLETMIGoek.dk> wrote
[8<8<8<]
> class B extends A {
> public Foo foo;
> public B { super(); }
> public void initialize() { // overriding A..
> // foo peger på u-initialiseret memory
> // idet kun A er constructed...
Når jeg inspicerer med en debugger er foo null
[8<8<8<]
> //main
> B b = new B; //crash
Det crasher ikke for mig under Sun Java HotSpot Client VM JDK 1.3.1 og
heller ikke under JDK 1.2.2
Hvilken bruger du ?
Efter b er constructed, kan jeg inspicere den og den har de forventede
værdier.
Jeg går ud fra at du har set det crashe tidligere.
Du kan ikke have kørt den postede kode, for der er et par småfejl i den
(mangler et par parenteser, en stavefejl).
Du mener at det burde crashe, men jeg ser det kører.
Jeg kan godt se hvor du vil hen, men mangler der en krølle et eller andet
sted ?
Mener du så at det er undefined behaviour ?
I givet fald i henhold til hvilken reference ?
Venlig hilsen
Mogens Hansen
PS
Det test-kode jeg kørte med:
<code>
package test;
import java.lang.*;
class A {
public A() { initialize(); }
protected void initialize() { }
}
class B extends A {
public Integer foo;
public B() { super(); }
public void initialize() { // overriding A..
// foo peger på u-initialiseret memory
// idet kun A er constructed...
foo = new Integer(1);
}
}
public class Application {
public static void main(String[] args) {
B b = new B();
}
}
</code>
| |
Esben Mose Hansen (10-08-2002)
| Kommentar Fra : Esben Mose Hansen |
Dato : 10-08-02 11:15 |
|
Mogens Hansen wrote:
> "Esben Mose Hansen" <esben@SLETMIGoek.dk> wrote
>
> [8<8<8<]
>
>>class B extends A {
>> public Foo foo;
>> public B { super(); }
>> public void initialize() { // overriding A..
>> // foo peger på u-initialiseret memory
>> // idet kun A er constructed...
>
>
> Når jeg inspicerer med en debugger er foo null
>
> [8<8<8<]
>
>>//main
>> B b = new B; //crash
>
>
> Det crasher ikke for mig under Sun Java HotSpot Client VM JDK 1.3.1 og
> heller ikke under JDK 1.2.2
> Hvilken bruger du ?
> Efter b er constructed, kan jeg inspicere den og den har de forventede
> værdier.
Også hos mig. Jeg kan huske galt, men den "rene" B-del af B er
så-vidt-jeg-erindrer ikke konstrueret endnu. However, så skulle man da
være en sær kompiler-skriver-snegl hvis man ikke allokerede og memsatte
hele B inden man startede Constructor'ne i det hele taget, så i praksis
er det nok ikke så farligt.
>
> Jeg går ud fra at du har set det crashe tidligere.
Nej, kun overraksende (=undefined formoder jeg) opførsel, som stammede
fra en glemt "final" og et uheldigt navneoverlap.
> Du kan ikke have kørt den postede kode, for der er et par småfejl i den
> (mangler et par parenteser, en stavefejl).
Guilty as charged. Her er en kørbar version
public class Aclass {
public Aclass() {
initialize();
}
public void initialize() {
System.out.println("Aclass::Initialize");
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.myString);
return;
}
}
class B extends Aclass {
public B() {
super();
}
public void initialize() {
System.out.println("B::Initialize");
System.out.println((myString==null)?"null":myString);
myString = new String("Hallo World");
}
public String myString = new String("Davs");
}
puha, jeg havde helt glemt hvor #¤%"#&&/# %&/ classpath's kan være
Iøvrigt synes jeg det er en fejl i javac at den ikke giver så meget som
en warning over initialize() kaldet. Uanset hvordan man ser på det er
det (næsten?) altid en fejl...
> Du mener at det burde crashe, men jeg ser det kører.
Jeg huskede jeg havde læst at det kunne crashe, men jeg har aldrig set
det. (Det crasher jo nok også på en pæn måde, det ER jo Java.. men netop
derfor bider den slags overraskelser ekstra hårdt.)
> Jeg kan godt se hvor du vil hen, men mangler der en krølle et eller andet
> sted ?
I min hjerne, formoder jeg
> Mener du så at det er undefined behaviour ?
> I givet fald i henhold til hvilken reference ?
Ok, efter lidt gavning på nettet ser jeg du/I har ret. Hukommelsen er
allokeret og initilialiseret til default værdien, det er bare
constructoren der mangler.
http://mindprod.com/gotchas.html#OVERRIDE
--
mvh. Esben
home.worldonline.dk/~mesben
| |
Bjarke Dahl Ebert (10-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 10-08-02 02:00 |
|
"Esben Mose Hansen" <esben@SLETMIGoek.dk> wrote in message
news:3D543FA8.2060604@SLETMIGoek.dk...
> Bjarke Dahl Ebert wrote:
> > Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et
destrueret
> > objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som
underklasse)
> > eller null.
>
> <grin> virkeligt? Watch me!
> [eksempel]
Er dette virkelig sandt? Det ville jeg betragte som en fejl i
implementationen. Jeg har ikke lige en Java ved hånden nu - er der ikke en
der kan poste det eventuelle "bevis" - jeg nægter at tro det før jeg ser det
:).
Ikke engang i C++ ville det crashe!
> // foo peger på u-initialiseret memory
> // idet kun A er constructed...
Der er vel "no such thing" som uinitialiseret memory. I værste fald skulle
foo være null.
> foo = new Foo();
Er der her du mener det crasher?
> "Tricket" er at forbryde sig mod at kalde non-final metoder i en
> constructor :) Det er nemmere i C++, men det bider hårdere i Java :D
I den tilsvarende C++-kode, ville der ske følgende:
1) new B()
2) A::A() bliver kaldt
3) initialize() kaldes
4) Dette er A::initialize, ikke B::initialize, selvom den er virtuel!
Dette skyldes at sålænge A er ved at blive konstrueret, så er objektet en A,
ikke en B. Så kald af virtuelle funktioner vil få fat i A's. På denne måde
kan man faktisk risikere at forårsage en "pure virtual function called" (jeg
havde tidligere *undret* mig over hvordan det kunne ske i C++, men det er
forklaringen).
Mvh. Bjarke
| |
Esben Mose Hansen (10-08-2002)
| Kommentar Fra : Esben Mose Hansen |
Dato : 10-08-02 11:01 |
|
Bjarke Dahl Ebert wrote:
> "Esben Mose Hansen" <esben@SLETMIGoek.dk> wrote in message
> news:3D543FA8.2060604@SLETMIGoek.dk...
>
>>Bjarke Dahl Ebert wrote:
>>
>>>Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et
>>
> destrueret
>
>>>objekt, og en "Foo f" kan KUN pege på et Foo-objekt (evt. som
>>
> underklasse)
>
>>>eller null.
>>
>><grin> virkeligt? Watch me!
>>[eksempel]
>
>
> Er dette virkelig sandt? Det ville jeg betragte som en fejl i
> implementationen. Jeg har ikke lige en Java ved hånden nu - er der ikke en
> der kan poste det eventuelle "bevis" - jeg nægter at tro det før jeg ser det
> :).
Det er fint at tvivle, men hvis du oversætter det til C++ kan du se at
det også går galt der (ifølge "Effective C++, 50 ways to improve..
forfatteren hedder vist Joshua eller sådan noget). Jeg har dog aldrig
selv skrevet det i C++, og min Linux disk er lige crashet, så jeg kan
ikke teste Og jeg er temmelig menneskelig
>
> Ikke engang i C++ ville det crashe!
sorry.
>
>
>> // foo peger på u-initialiseret memory
>> // idet kun A er constructed...
>
>
> Der er vel "no such thing" som uinitialiseret memory. I værste fald skulle
> foo være null.
Undskyld. s/uinitialiseret/måske uallokeret/
>
>
>> foo = new Foo();
>
>
> Er der her du mener det crasher?
Det er i hvert fald muligt. Hukommelsen til foo er ikke (nødvendigvis)
allokeret endnu.
>>"Tricket" er at forbryde sig mod at kalde non-final metoder i en
>>constructor :) Det er nemmere i C++, men det bider hårdere i Java :D
>
>
> I den tilsvarende C++-kode, ville der ske følgende:
> 1) new B()
> 2) A::A() bliver kaldt
> 3) initialize() kaldes
> 4) Dette er A::initialize, ikke B::initialize, selvom den er virtuel!
Det faktisk B::initialize... efter sigende. Har kun testet det i Java.
Jeg kan sagtens tage fejl.
> Dette skyldes at sålænge A er ved at blive konstrueret, så er objektet en A,
> ikke en B. Så kald af virtuelle funktioner vil få fat i A's. På denne måde
> kan man faktisk risikere at forårsage en "pure virtual function called" (jeg
> havde tidligere *undret* mig over hvordan det kunne ske i C++, men det er
> forklaringen).
Det lyder meget plausibelt, men jeg skal ikke kunne sige det. Som jeg
husker det /burde/ det være B::initialize() der bliver kaldt, men den
compiler jeg bruger til dagligt giver warnings hvis man kalder virtuelle
funktioner fra constructore... så jeg har ikke lavet den brøler endnu.
(Javac er derimod kold )
--
mvh. Esben
home.worldonline.dk/~mesben
| |
Mogens Hansen (10-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 10-08-02 12:10 |
|
"Esben Mose Hansen" <esben@SLETMIGoek.dk> wrote in message
news:3D54E446.4060607@SLETMIGoek.dk...
> Bjarke Dahl Ebert wrote:
[8<8<8<]
> Det er fint at tvivle, men hvis du oversætter det til C++ kan du se at
> det også går galt der
Hvad forståes ved "det går galt" ?
Det er veldefineret hvad der sker i C++: A::initialize bliver kaldt.
Det er muligvis overraskende for nogen - men der er en god forklaring, som
forekommer mig at være intuitiv. Men som (så vidt jeg husker) Igor V.
Rafienko siger: kun brystvorten er intuitiv - alt andet er tillært.
> (ifølge "Effective C++, 50 ways to improve..
> forfatteren hedder vist Joshua eller sådan noget).
Forfatteren hedder Scott Meyers.
[8<8<8<]
> > I den tilsvarende C++-kode, ville der ske følgende:
> > 1) new B()
> > 2) A::A() bliver kaldt
> > 3) initialize() kaldes
> > 4) Dette er A::initialize, ikke B::initialize, selvom den er virtuel!
>
> Det faktisk B::initialize... efter sigende. Har kun testet det i Java.
> Jeg kan sagtens tage fejl.
I C++ bliver A::initialize kaldt (i henhold til specifikationen).
I Java bliver B::initialize kaldt (testet på 2 forskellige VM'er).
> > Dette skyldes at sålænge A er ved at blive konstrueret, så er objektet
en A,
> > ikke en B. Så kald af virtuelle funktioner vil få fat i A's. På denne
måde
> > kan man faktisk risikere at forårsage en "pure virtual function called"
(jeg
> > havde tidligere *undret* mig over hvordan det kunne ske i C++, men det
er
> > forklaringen).
>
> Det lyder meget plausibelt, men jeg skal ikke kunne sige det. Som jeg
> husker det /burde/ det være B::initialize() der bliver kaldt, men den
> compiler jeg bruger til dagligt giver warnings hvis man kalder virtuelle
> funktioner fra constructore... så jeg har ikke lavet den brøler endnu.
Hvis vi snakker C++ så husker du forkert - ingen tvivl.
Generelt er det vanskelligt for en C++ compiler at give sådan en warning.
Constructoren kan kalde en funktion, som kalder en funktion, som ..., som
kalder en virtuel funktion (som måske ikke findes!).
Det vil kræve at compileren har overblik over _hele_ programmet og ikke kun
een compilation unit - kun få C++ compilere har det overblik.
Venlig hilsen
Mogens Hansen
| |
Per Abrahamsen (06-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 06-08-02 15:25 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
> news:rjy9bll0vu.fsf@zuse.dina.kvl.dk...
>
>> "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
>>
>> > Men lavniveau er "slået til" hele tiden i C++, på godt og ondt. Man har
> ikke
>> > garbage-collection, der er ingen automatiske runtimechecks (kun dem man
> selv
>> > laver), dvs. specielt ingen arraybound-checking, check af at en
> reference
>> > stadig peger på et gyldigt objekt, check af at objektet faktisk har den
> type
>> > som pointervariablen er kvalificeret med, osv.
>>
>> Ovenstående features afhænger af implementationen.
>
> Ja, men stort set alle implementationer har det som beskrevet af ovenstående
> features. Standarden forlanger derfor selvfølgelig heller ikke disse
> features, og at bero på dem ville binde en til en bestemt implementation.
Bortser fra garbage collection kan man ikke "bero" på nogen af de
features. Faktisk vil det oftest være lettere at flytte koden fra en
implementation med de features, end fra en implementation uden de
features.
> Jeg opfatter snarere de nævnte features som nogle ting der kan få
> højniveauet abstraheret mere væk fra lavniveauet.
Jeg kan ikke se nogen rationel begrundelse for en sådan opfattelse.
> Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et destrueret
> objekt,
Selvfølgelig kan den det. Den kan ikke gøre det på sprogniveauet, men
sagtens på design niveauet. At noget ikke er en fejl på sprogniveauet
er ikke den store hjælp, hvis det er en fejl på design niveauet.
> og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
> eller null.
I C++ kan f med ovenstående definition KUN være et Foo objekt, aldrig
en underklasse eller nil.
> Nej, std::string og nested scope henregner jeg til højniveau-fænomener.
Og begynderen skal lære char* og referencesemantik først?
> Det jeg siger er at der i C++'s måde at håndtere disse højniveauting på
> skinner ting igennem der hører lavniveau til. Fx kan man i C++ stadig kigge
> på den plads hvor strengen engang lå, men den vil være væk, og der vil evt.
> ligge noget andet.
Nej, ikke hvis man kun bruger værdier.
Selvfølgelig skal porgrammøren lære at bruge pointere, men det er ikke
der han skal starte.
| |
Soeren Sandmann (06-08-2002)
| Kommentar Fra : Soeren Sandmann |
Dato : 06-08-02 16:09 |
|
Per Abrahamsen <abraham@dina.kvl.dk> writes:
> > og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
> > eller null.
>
> I C++ kan f med ovenstående definition KUN være et Foo objekt, aldrig
> en underklasse eller nil.
Den tilsvarende C++-erklæring er "Foo *f", og den pointer kan pege på
hvad som helst: nul, andre objekter af en helt anden type end Foo,
tilfældig hukommelse, et Foo-objekt eller noget der engang var et
Foo-objekt. Der er ikke noget tilsvarende C++'s "Foo f" i Java.
Javas type- og runtimesystemer sikrer at "Foo f" aldrig nogensinde
peger på andet end null eller et objekt at type Foo.
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 17:30 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
news:rjy9bkjc98.fsf@zuse.dina.kvl.dk...
> > Jeg opfatter snarere de nævnte features som nogle ting der kan få
> > højniveauet abstraheret mere væk fra lavniveauet.
>
> Jeg kan ikke se nogen rationel begrundelse for en sådan opfattelse.
Jeg tror du klippede min rationelle begrundelse væk
De nævnte features sikrer at man ikke kan se de mest skumle
lavniveau-detaljer.
Hvis man kan se lavniveau-tingene, og endda komme til at pille ved dem ved
en fejltagelse, så står højniveautingene på gyngende grund.
> > Sådan opfatter jeg det ikke. I Java kan man fx ikke pege på et
destrueret
> > objekt,
>
> Selvfølgelig kan den det. Den kan ikke gøre det på sprogniveauet, men
> sagtens på design niveauet. At noget ikke er en fejl på sprogniveauet
> er ikke den store hjælp, hvis det er en fejl på design niveauet.
I det mindste får man en veldefineret fejl.
En fejl er ikke så slem, hvis den konsekvent forårsager at tests fejler.
Problemet med fx løbske pointere at at man kan få fejl som kun vanskeligt
kan reproduceres. Til sidst står man i desperation og svinger en død høne
over maskinen, fordi man mener at kunne huske at det hjalp sidste gang.
> > og en "Foo f" kan KUN pege på et Foo-objekt (evt. som underklasse)
> > eller null.
>
> I C++ kan f med ovenstående definition KUN være et Foo objekt, aldrig
> en underklasse eller nil.
"Foo f" betyder noget forskelligt i Java og C++, men lad os bare se på "Foo
f" i C++ alligevel:
Foo f;
*(char*)(&f) = '!';
Her var det selvfølgelig med vilje, men noget tilsvarende kan godt ske ved
et uheld. Derfor er højniveau ikke adskildt ret godt fra lavniveau. Jeg kan
ikke "designe" mig ud af den slags fejl - jeg kan ikke forhindre en lille
afkrog af min applikation i at smadre min lokale Foo. Højniveau'et bryder
sammen, når jeg ikke kan være sikker på at der er en Foo i min Foo.
Hele humlen ligger i følgende udsagn: "Jeg kan godt lade være med at bruge
(char*), men jeg kan ikke forhindre andre eller mig selv i at gøre det ved
et uheld".
> > Det jeg siger er at der i C++'s måde at håndtere disse højniveauting på
> > skinner ting igennem der hører lavniveau til. Fx kan man i C++ stadig
kigge
> > på den plads hvor strengen engang lå, men den vil være væk, og der vil
evt.
> > ligge noget andet.
>
> Nej, ikke hvis man kun bruger værdier.
Nej, men det er umuligt at sikre. Selv hvis jeg ikke ønsker at bruge
pointere eller referencer, kan jeg komme til det alligevel ved et uheld (fx
ved at oprette et objekt hvis constructor tager en reference-parameter), og
andre der skriver kode i samme program kan gøre hvad de vil.
> Selvfølgelig skal porgrammøren lære at bruge pointere, men det er ikke
> der han skal starte.
Jeg kender mange der har C som deres første sprog, og det er ikke så svært
som man gør det til. Det er svært at programmere i C eller C++, hvis man
*ikke* får noget at vide om pointere. Også i starten, vil jeg mene.
Bjarke
| |
Mogens Hansen (06-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 06-08-02 20:13 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:3d4ff999$0$78201$edfadb0f@dspool01.news.tele.dk...
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
> news:rjy9bkjc98.fsf@zuse.dina.kvl.dk...
[8<8<8<]
> > Selvfølgelig skal porgrammøren lære at bruge pointere, men det er ikke
> > der han skal starte.
>
> Jeg kender mange der har C som deres første sprog, og det er ikke så svært
> som man gør det til. Det er svært at programmere i C eller C++, hvis man
> *ikke* får noget at vide om pointere. Også i starten, vil jeg mene.
Hvem i denne tråd har sagt eller antydet at man ikke skal lære noget om
pointere, hvis man vil lære C++ ?
Det er en påstand som du har opfundet, og fortsat erklærer dig uenig i.
Det er din egen forudintagede holdninger om hvad du tror andre mener, som du
diskuterer med.
Venlig hilsen
Mogens Hansen
| |
Anders J. Munch (06-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 06-08-02 18:56 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> skrev:
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
>
> > "Per Abrahamsen" <abraham@dina.kvl.dk> wrote:
> >
> >> "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> > Det jeg siger er at der i C++'s måde at håndtere disse højniveauting på
> > skinner ting igennem der hører lavniveau til. Fx kan man i C++ stadig
kigge
> > på den plads hvor strengen engang lå, men den vil være væk, og der vil
evt.
> > ligge noget andet.
>
> Nej, ikke hvis man kun bruger værdier.
>
> Selvfølgelig skal porgrammøren lære at bruge pointere, men det er ikke
> der han skal starte.
Uden pointere i en eller anden form er der ikke ret meget køretidspolymorfi.
Hvad sjov er der ved objektorienteret programmering hvis man ikke kan lave
en heterogen container?
- Anders
| |
Per Abrahamsen (06-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 06-08-02 15:31 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> Det er blandt andet dette, jeg mener med at man har lavniveau slået til hele
> tiden.
Det virker uhensigtsmæssigt at bruge en implementationsafhængig
definition af "lavniveau" i en sprogdiskussion.
Og jeg kan slet ikke se hvordan en sådan definition kan være relevant
for den rækkefølge en begynder bør lære et sprog.
Altså hvordan en implementation reagerer på en fejl bør efter din
mening afgøre i hvilken rækkefølge en begynder bør lære sproget at
kende?
| |
Bjarke Dahl Ebert (06-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-08-02 16:57 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
news:rjr8hcjbyj.fsf@zuse.dina.kvl.dk...
> Altså hvordan en implementation reagerer på en fejl bør efter din
> mening afgøre i hvilken rækkefølge en begynder bør lære sproget at
> kende?
Ja.
Hvis det begynder at blive normen at implementationer tilbyder veldefinerede
fejl i stedet for undefined behaviour, så ville jeg nok revurdere min
mening.
Bjarke
| |
Per Abrahamsen (06-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 06-08-02 16:00 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> writes:
> Han kender desuden en lang række andre sprog - som bl.a. har været brugt i
> forbindelse med produktionen af "Accelerated C++".
Han er også en ret enthusiastisk SML programmør.
> Ligeså snart man har skrevet
>
> int main(void)
>
> har man brugt dele af C subsettet.
Bør man ikke også skrive
int main ()
i C++?
Så vidt jeg husker var (void) en feature man indførte i C for at kunne
skelne en funktion uden argumenter fra en gammeldags
funktionserklæring. C++ droppede den gamle syntaks med det samme, og
indførte først (void) senere for at være kompatibel.
| |
Mogens Hansen (06-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 06-08-02 20:16 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote
> Bør man ikke også skrive
>
> int main ()
>
> i C++?
Jo, det er mest indfødt - selvom det andet ikke er formelt forkert. Tak.
Jeg er ved at vende mig fra det.
Du understreget blot min pointe: dårlige vaner hænger mere fast end man
bryder sig om at indrømme.
Jeg lærte C for 13 år siden, og noget hænger forsat ved.
Venlig hilsen
Mogens Hansen
| |
Per Abrahamsen (07-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-08-02 11:28 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> writes:
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote
>
>> Bør man ikke også skrive
>>
>> int main ()
>>
>> i C++?
>
>
> Jo, det er mest indfødt - selvom det andet ikke er formelt forkert. Tak.
> Jeg er ved at vende mig fra det.
> Du understreget blot min pointe: dårlige vaner hænger mere fast end man
> bryder sig om at indrømme.
> Jeg lærte C for 13 år siden, og noget hænger forsat ved.
Heldigvis var "int main (void)" en syntaksfejl dengang jeg lærte C, så
det ser stadig underligt ud for mig.
Jeg tror faktisk jeg lærte C++ før ANSI C.
| |
Per Abrahamsen (07-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-08-02 11:56 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> Opfatter du det som en "C++ revisited" der dropper bagudkompatibilitet på
> betydningsfulde punkter, eller opfatter du det som en gradvis udlugning af
> uønsket syntaks/"mekanismer" i en iterativ proces over flere år, hvor
> softwaren kan nå at følge med?
>
> Jeg mener at det mest realistiske vil være det første.
Det mest realistiske er den anden, eftersom det er en process der
allerede er i gang.
Jeg tror ikke "C++ revisited" er et konkret project eller specielt
ønskeligt, det var vist mere en strøtanke.
>> Hvis man vil se en flig af hvordan syntaksen måske kunne være, så side 22
>> af http://www.klid.dk/arrangementer/XTI_kbh.pdf
>
> Øh? Taler vi om siden med overskriften "External XTI"?
Det vil jeg tro. Jeg har set BS kalde C's syntaks for erklæringer for
"a failed eksperiment" et eller andet sted, så det er ikke så
overraskende at han vælger en Pascal syntaks i stedet. Det er et sted
hvor C++ (og C) syntaktisk set kunne blive meget forenklet.
Mere generelt er der nok tale om en række småting der kun er der for C
kompatibilitet. F.eks. at "tekst" har typen char *const og ikke
std::string (eller bare const char *const).
Hvorfor kan man f.eks ikke skrive:
const string foo = "world";
const string bar = "hello " + world;
?
Det er et af de steder hvor man som ny bruger alt for hurtigt skal
gøres bekendt med C delen (apropos tidligere diskussion).
| |
Mogens Hansen (07-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 07-08-02 14:15 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote
> Jeg tror ikke "C++ revisited" er et konkret project eller specielt
> ønskeligt, det var vist mere en strøtanke.
Jeg tror heller ikke på det.
Det er interesant at kigge tilbage på hvad der er godt og skidt, men man kan
ikke ændre fortiden.
Som tanke-eksperiment er en alternativ syntaks underholdende nok. Men det
stopper også der.
Der er investeret for mange penge i eksisterende kode, til at man bare kan
klippe det væk.
Syntaxen i C++ virker jo faktuelt også for millioner af programmører verden
over - så det er langtfra umuligt at lære.
Når man har lært den, er det nogenlunde ligegyldigt.
Bjarne Stroustrup siger (D&E, side 207): "I maintain that C++'s type system
and semantics are cleaner than its syntax".
Spørgsmålet vil jo være om fordelene ved "den perfekte syntaks" vil opveje
ulemperne i forhold til alt eksisterende arbejde.
Det svarer jo til at vi skulle holde op med at snakke dansk, fordi det ikke
er helt simpelt og regelret i alle kanter:
en bil, flere biler
en blomst, flere blomster
en sten, flere sten - ikke flere stener
en cykel, flere cykler
en heste, flere heste
en gås, flere gæs
men vi er omtrent 5 millioner mennesker der kan få det til at fungere - og
det bekymrer os end ikke.
Et sidespring:
Det pudsige er, at netop syntaksen er en af de ting Java og C# har mest til
fælles med C++ - og de startede endda fra et blankt stykke papir.
Venlig hilsen
Mogens Hansen
| |
Klaus Kolle (07-08-2002)
| Kommentar Fra : Klaus Kolle |
Dato : 07-08-02 22:31 |
|
On Wed, 7 Aug 2002 15:14:44 +0200, "Mogens Hansen"
<mogens_h@dk-online.dk> wrote:
>Det svarer jo til at vi skulle holde op med at snakke dansk, fordi det ikke
>er helt simpelt og regelret i alle kanter:
> en bil, flere biler
> en blomst, flere blomster
> en sten, flere sten - ikke flere stener
> en cykel, flere cykler
> en heste, flere heste
> en gås, flere gæs
>men vi er omtrent 5 millioner mennesker der kan få det til at fungere - og
>det bekymrer os end ikke.
>
>Et sidespring:
Ja nu har jeg fulgt denne interessante meningsudveksling, som jo når
ud i krogene , så derfor et et sidespring vel på sin plads. Jeg
blev inspireret af ovenstående og fandt på Ingeniørens bagside i
klasikkerarkivet denne:
Vi starter med lås, der i flertal er låse,
men flertal af gås er gæs - ikke gåse.
Vi taler om fod, er der fler', si'r vi fødder,
men skønt vi si'r flod, vi aldrig si'r flødder.
Er der én, er det den, er der to, si'r man disse.
Hvorfor fa'n hedder pen så - pluralt - ikke pisse?
At flertal af mand er mænd - ikke mænner,
er svært at forstå, når én tand bli'r til tænder.
Skønt flertal af and som bekendt hedder ænder,
så hører man aldrig at spand bli'r til spænder.
En anden mærkværdighed her til lands:
I tredje person er det han, ham og hans.
Er det sund logik - ja derom spø'r jeg kuns -
man ikke om damer si'r hun, hum og huns.
At synge i datid på dansk hedder sang,
men gynges imperfektum er ikke gang.
Og hvem kan forstå, hvorfor spring er sprang,
når bringe det ikke i datid er brang?
Korrekt hedder datid af bringe jo bragte,
hvor er så logikken, når man siger bagte
på basis af infinitiven at bage?
Et andet eksempel: Det hedder "at tage".
Det bøjes til datid ved, at man si'r tog.
Sku' bage så ikke i datid gi' bog?
Når bringe er bragte, sku' bagte vær' binge,
men så måtte ragte vær' datid af ringe,
og ragte det findes på dansk faktisk ikke.
Derfor må vi hel're la' spørgsmålet ligge.
Og det er jo så er spørgsmål om ikke dette lille espistel kunne bringe
os sammen om at programmere uanset "uregelmæssige bøjninger" af det
ene eller andet sprog.
mvh
Klaus Kolle
| |
Bjarke Dahl Ebert (07-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 07-08-02 23:12 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
news:rjy9bjaqex.fsf@zuse.dina.kvl.dk...
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> > Øh? Taler vi om siden med overskriften "External XTI"?
> Det vil jeg tro. Jeg har set BS kalde C's syntaks for erklæringer for
> "a failed eksperiment" et eller andet sted,
Hehe - ja, det er jeg enig i.
Så sent som igår stødte jeg på et problem relateret til dette. "Foo(a);"
parses åbenbart ikke som et udtryk der skaber et temporært objekt af typen
Foo. Derimod erklærer det en variabel, a, af typen Foo (det er i hvert fald
min fortolkning af hvad der sker).
Ja, hvornår ville man skrive "Foo(a);" - det ville vi, fordi Foo har en
constructor med nogle sideeffekter vi er ude efter - ikke så fedt design kun
at have denne kode i en constructor, men det er uden for vores kontrol.
Vi løste det med "Foo dummy(a);". Det viste sig iøvrigt at compileren
(MSVC6.0) også åd "Foo::Foo(a)" - er det lovligt?
> Hvorfor kan man f.eks ikke skrive:
>
> const string foo = "world";
> const string bar = "hello " + world;
>
> ?
Det kan man vel også - altså, efter "using std;"? (Jeg antager at den sidste
world skulle have været foo).
Men jeg ved måske godt hvor du vil hen... litteral strings har stadig
strengtypen fra C, endda efter alle kunstens regler med nulterminering, så
sizeof("foo") er vel 4. Hvis jeg ikke tager meget fejl, så har "foo" typen
char[4] (ikke const char*), og det er undefined at assigne til "foo"[0].
Det ville nok være renere hvis "Foo" havde typen const std::string. Jeg er
desværre ikke sikker på at alle compilerleverandører ville være henrykte
. Iøvrigt er jeg heller ikke selv helt overbevist om det lykkelige i det.
En fordel ved at "foo" er en char[], er at typen er med i "core language" og
dermed ikke favoriserer noget bestemt library (uanset at det er standard).
Man kunne jo i særlige situationer have lyst til at gå udenom
standardlibrariet (fx i visse embeddede applikationer), og forslaget ville
nok også binde hver compiler til en bestemt std::string implementation.
Mvh. Bjarke
| |
Mogens Hansen (08-08-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 08-08-02 04:43 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:mYg49.7096$G3.903828@news010.worldonline.dk...
> "Per Abrahamsen" <abraham@dina.kvl.dk> wrote in message
> news:rjy9bjaqex.fsf@zuse.dina.kvl.dk...
>
[8<8<8<]
> > Hvorfor kan man f.eks ikke skrive:
> >
> > const string foo = "world";
> > const string bar = "hello " + world;
> >
> > ?
>
> Det kan man vel også - altså, efter "using std;"? (Jeg antager at den
sidste
> world skulle have været foo).
>
> Men jeg ved måske godt hvor du vil hen... litteral strings har stadig
> strengtypen fra C, endda efter alle kunstens regler med nulterminering, så
> sizeof("foo") er vel 4. Hvis jeg ikke tager meget fejl, så har "foo" typen
> char[4] (ikke const char*), og det er undefined at assigne til "foo"[0].
"foo" er af typen "const string", og den er initialiseret med en string
litteral "world".
"sizeof(foo)" er derfor det samme som sizeof(std::string) - typisk mere end
4. Der skal typisk mindst være plads til:
* pointer til heap område med teksten
* størrelse på teksten
* størrelse på heap området
Så sizeof (foo) vil nok ikke være mindre end 12 på en typisk 32 bit maskine.
Når programmet vil "world" være at finde 2 steder:
1. I konstant data-område, hvor man ikke må skrive og ofte heller ikke
kan.
F.eks. i kode-segmentet under MS-Windows (forsøg på skrivning kan give GPF)
eller i ROM på et embedded system (forsøg på skrivning gør ændrer intet,
evt. bus-error).
2. I forbindelse med "foo" objektet. Typisk på det sted på heapen, hvortil
"foo" har en peger.
Venlig hilsen
Mogens Hansen
| |
Bjarke Dahl Ebert (08-08-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 08-08-02 09:55 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aisp2g$18um$1@news.cybercity.dk...
>
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
> > Det kan man vel også - altså, efter "using std;"? (Jeg antager at den
> sidste
> > world skulle have været foo).
> > Men jeg ved måske godt hvor du vil hen... litteral strings har stadig
> > strengtypen fra C, endda efter alle kunstens regler med nulterminering,
så
> > sizeof("foo") er vel 4. Hvis jeg ikke tager meget fejl, så har "foo"
typen
> > char[4] (ikke const char*), og det er undefined at assigne til "foo"[0].
>
> "foo" er af typen "const string", og den er initialiseret med en string
> litteral "world".
Hov! Jeg kan nu se en frygtelig ambiguity .
Jeg skrev "foo", ikke foo - jeg tænkte ikke lige på at Pers variabel også
hed foo. Jeg mente litteral string "foo".
Måske skulle jeg have skrevet "\"foo\""
Mvh. Bjarke
| |
Martin M. Pedersen (08-08-2002)
| Kommentar Fra : Martin M. Pedersen |
Dato : 08-08-02 18:17 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:aisp2g$18um$1@news.cybercity.dk...
> "foo" er af typen "const string", og den er initialiseret med en string
> litteral "world".
> "sizeof(foo)" er derfor det samme som sizeof(std::string) - typisk mere
end
> 4. Der skal typisk mindst være plads til:
> * pointer til heap område med teksten
> * størrelse på teksten
> * størrelse på heap området
> Så sizeof (foo) vil nok ikke være mindre end 12 på en typisk 32 bit
maskine.
Der er ikke noget i vejen for, at en string blot er en pointer til noget
heap med både tekst og kontrolinformation. Under Linux med g++ her hos mig
er den eneste non-static member således en 'dat' pointer, og
sizeof(std::string) er 4. Med MSVC6 får jeg sizeof(std::string) til 16.
Begge benytter i øvrigt en delt representation, så udover ovenstående
kontrolinformation er der også brug for en reference-counter.
mvh.
Martin
| |
Per Abrahamsen (07-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-08-02 12:20 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> De nævnte features sikrer at man ikke kan se de mest skumle
> lavniveau-detaljer. Hvis man kan se lavniveau-tingene, og endda
> komme til at pille ved dem ved en fejltagelse, så står
> højniveautingene på gyngende grund.
Og hvad har det med indlæring at gøre?
> Problemet med fx løbske pointere at at man kan få fejl som kun vanskeligt
> kan reproduceres. Til sidst står man i desperation og svinger en død høne
> over maskinen, fordi man mener at kunne huske at det hjalp sidste gang.
Eller man bruger et værktøj som valgrind der fanger dem.
Du bliver ved med at angive gode argumenter for at en begynder bør
bruge et værktæj med gode runtime checks, som argument for at
begyndere bør C før C++.
GCC kan give en advarsel hvis du bruger (char*). Den har jeg slået
til.
> Hele humlen ligger i følgende udsagn: "Jeg kan godt lade være med at bruge
> (char*), men jeg kan ikke forhindre andre eller mig selv i at gøre det ved
> et uheld".
"Ups, mine fingre smuttede, jeg kom til at skrive (char*)."
Den slags "kommer man til" betydeligt lettere hvis man har lært C
(eller et C-lignede subset af C++) før man lærer "rigtig" C++. Så det
må om noget et argument for at lære C++ ovenfra og ned, i stedet for
at starte med at lære alle de dårlige vaner.
Det er faktisk en gammel kliche at det tager længere tid at lære folk
at skrive i Pascal hvis de først har lært BASIC, fordi de først skal
aflære en masse dårlige vaner. Jeg tror de fleste der har undervist
begyndere i programmering vil kunne nikke genkendende til det udsagn i
en eller anden variant.
For os der *har* lært C før C++, har GCC heldigvis mulighed for at
give en advarsel hvis man bruger (char*). Den har jeg slået til.
> Nej, men det er umuligt at sikre. Selv hvis jeg ikke ønsker at bruge
> pointere eller referencer, kan jeg komme til det alligevel ved et uheld (fx
> ved at oprette et objekt hvis constructor tager en reference-parameter), og
> andre der skriver kode i samme program kan gøre hvad de vil.
Du har virkelig problemer med at styre dine fingre.
>> Selvfølgelig skal porgrammøren lære at bruge pointere, men det er ikke
>> der han skal starte.
>
> Jeg kender mange der har C som deres første sprog, og det er ikke så svært
> som man gør det til. Det er svært at programmere i C eller C++, hvis man
> *ikke* får noget at vide om pointere. Også i starten, vil jeg mene.
Jeg har svært ved at tage den mening alvorligt fra en der ikke skelner
mellem C og C++ i den sammenhæng.
| |
Per Abrahamsen (07-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-08-02 12:28 |
|
"Anders J. Munch" <andersjm@inbound.dk> writes:
> Uden pointere i en eller anden form er der ikke ret meget køretidspolymorfi.
> Hvad sjov er der ved objektorienteret programmering hvis man ikke kan lave
> en heterogen container?
Jeg mener heller ikke man skal starte med OOP. Start med enkle
programmer der kan være i main (som "hello world"), fortsæt man
opdeling i funktioner, gå videre med object based programmering
(moduler/klasser, inheritence, i den rækkefølge), før vi kommer til
OOP (virtuelle funktioner) og til sidst generisk programmering
(templates).
Referencer bør nok dukke op mellem funktioner og object based
programmering (OBP), eller evt. mellem OBP og OOP.
| |
Per Abrahamsen (07-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-08-02 12:30 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
> Hvis det begynder at blive normen at implementationer tilbyder veldefinerede
> fejl i stedet for undefined behaviour, så ville jeg nok revurdere min
> mening.
Hvorfor skal det være normen? Er det ikke nok at det er tilfældet for
den specifikke implementation begynderen bruger?
| |
Per Abrahamsen (07-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-08-02 14:36 |
|
Per Abrahamsen <abraham@dina.kvl.dk> writes:
> Jeg mener heller ikke man skal starte med OOP.
Det er nok for stærkt sagt. Jeg ville ikke starte med OOP, men jeg
kan sagtens forestille mig et fornuftigt kursus der startede sådan.
| |
Per Abrahamsen (12-08-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 12-08-02 10:21 |
|
"Anders J. Munch" <andersjm@inbound.dk> writes:
> Har du i øvrigt lagt mærke til, at C++-stil-programmerne er O(n^2)?
> std::string behøver jo ikke bruge eksponentiel allokering,
Er du sikker? Jeg har ikke standarden, men noget diskussion i GCC bug
listen gav mig det indtryk at det var et krav i standarden..
> og der er implementationer der ikke gør det.
Det er så rigtigt nok.
| |
Anders J. Munch (12-08-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 12-08-02 13:33 |
|
"Per Abrahamsen" <abraham@dina.kvl.dk> wrote:
> "Anders J. Munch" <andersjm@inbound.dk> writes:
>
> > Har du i øvrigt lagt mærke til, at C++-stil-programmerne er O(n^2)?
> > std::string behøver jo ikke bruge eksponentiel allokering,
>
> Er du sikker? Jeg har ikke standarden, men noget diskussion i GCC bug
> listen gav mig det indtryk at det var et krav i standarden..
Ret sikker. Brug vector<char> hvis du vil have gode kompleksitetsgarantier.
- Anders
| |
|
|