[Alg] Slechtste programmeervoorbeelden deel 3 Vorige deel Overzicht Volgende deel Laatste deel

Dit topic is onderdeel van een reeks. Ga naar het meest recente topic in deze reeks.

Pagina: 1 ... 7 ... 11 Laatste
Acties:
  • 71.183 views sinds 30-01-2008

Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
mosymuis schreef op woensdag 18 juni 2008 @ 10:40:
PHP:
1
2
3
4
5
6
7
8
9
10
    $sBedrijfSQL = "select * from tblBedrijf ORDER BY Naam";
    $sBedrijfQuery = mysql_query($sBedrijfSQL);
    while($aBedrijven = mysql_fetch_array($sBedrijfQuery))
    {
        $bedrijfindex = $aBedrijven['ID'];
        $sBedrijfSQLas = "select * from tblBedrijf where ID = '$bedrijfindex'";
        $sBedrijfQueryas = mysql_query($sBedrijfSQLas);
        $oBedrijf = mysql_fetch_assoc($sBedrijfQueryas);
        $aBedrijf[$bedrijfindex] = $oBedrijf;
    }

Wie mij de logica kan uitleggen krijgt een bloemetje }:O
WTF!?

mysql_query gebruiken? Is dat niet een beetje achterhaald? Dat is natuurlijk de echte WTF hier ;)

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • daniëlpunt
  • Registratie: Maart 2004
  • Niet online

daniëlpunt

monkey's gone to heaven

En dan nog die smerige Hongaarse notatie en lekker inconsistent met de hoofdletters in de eerste query.

Echt een juweeltje.

Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Eerst sorteren op naam, die ID's gebruiken en dan vervolgens een op ID gesorteerde array achterlaten. Nee, ik kan je niet helpen met de logica ;)

Naja, na de opmerking van super-muffin over de hoofdletters in de eerste query begin ik te vermoeden dat een tweede devver daar ooit de zinloze 'order by'-clause heeft toegevoegd.
super-muffin schreef op woensdag 18 juni 2008 @ 13:12:
En dan nog die smerige Hongaarse notatie
Hongaarse notatie? Ik zie geen hongaarse notatie, alleen maar vage prefixes ;). Hongaarse notatie is bij PHP trouwens nog best zinvol, aangezien de interpreter zelf geen type checking doet. Echt nodig is het niet, omdat je niet met ruwe words aan het gooien bent, maar toch :)

Acties:
  • 0 Henk 'm!

  • remco_k
  • Registratie: April 2002
  • Laatst online: 11-09 23:00

remco_k

een cassettebandje was genoeg

mosymuis schreef op woensdag 18 juni 2008 @ 10:40:
Wie mij de logica kan uitleggen krijgt een bloemetje }:O
Historisch gegroeide code is het. (hoop ik, want anders mag die software knakker z'n spullen gaan pakken).
Ooit stond de data die nodig is in andere tabellen. En in plaats van een JOIN vroeg hij die op met een query op een andere tabel in de while lus.
Maar dan nog is het niet erg logisch.

[ Voor 4% gewijzigd door remco_k op 18-06-2008 14:21 ]

Alles kan stuk.


Acties:
  • 0 Henk 'm!

  • djiwie
  • Registratie: Februari 2002
  • Laatst online: 11-09 22:26

djiwie

Wie?

Nee, want dan had je gewoon kunnen joinen...

Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
mosymuis schreef op woensdag 18 juni 2008 @ 10:40:
PHP:
1
2
3
4
5
6
7
8
9
10
    $sBedrijfSQL = "select * from tblBedrijf ORDER BY Naam";
    $sBedrijfQuery = mysql_query($sBedrijfSQL);
    while($aBedrijven = mysql_fetch_array($sBedrijfQuery))
    {
        $bedrijfindex = $aBedrijven['ID'];
        $sBedrijfSQLas = "select * from tblBedrijf where ID = '$bedrijfindex'";
        $sBedrijfQueryas = mysql_query($sBedrijfSQLas);
        $oBedrijf = mysql_fetch_assoc($sBedrijfQueryas);
        $aBedrijf[$bedrijfindex] = $oBedrijf;
    }

Wie mij de logica kan uitleggen krijgt een bloemetje }:O
(ssh, dat heb ik ook wel eens gedaan :'(. Comments voor een bepaalde nieuwpost uit een database halen. Ik schaam mij diep ondertussen)

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ook een leuk detail: $oBedrijf is geen object maar een array ;)

Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

YopY schreef op donderdag 19 juni 2008 @ 11:47:
[...]

(ssh, dat heb ik ook wel eens gedaan :'(. Comments voor een bepaalde nieuwpost uit een database halen. Ik schaam mij diep ondertussen)
Haha nou vind hem niet zo erg heb in mijn verleden wel ergere dingen op mijn kerfstok. Je begint toch met copy plakken en vage $tmpDit en $DoeHet variabelen om het te leren.

Hij deed het wel ;) of niet

[ Voor 10% gewijzigd door vorlox op 26-06-2008 18:26 ]


Acties:
  • 0 Henk 'm!

  • Tanuki
  • Registratie: Januari 2005
  • Niet online
YopY schreef op donderdag 19 juni 2008 @ 11:47:
[...]


(ssh, dat heb ik ook wel eens gedaan :'(. Comments voor een bepaalde nieuwpost uit een database halen. Ik schaam mij diep ondertussen)
Euh en wat is daar dan erg aan? Als je een join doet krijg je je nieuwsbericht (aantal comments) keer terug en daarnaast zul je dan weer met ifs moeten gaan klooien om het alsnog goed te krijgen.

Daarnaast is het sowieso onzinnig, want je wilt nooit de nieuwsberichten laten zien met daarbij meteen de comments. Daar heb je doorgaans een aparte pagina voor waar je bovenaan het nieuwsbericht ziet en daaronder de comments die bij dat ene bericht horen.

Als je voor dat laatste een join gaat gebruiken ben je imho wel heel erg micro-optimalistisch (is dat een woord?) bezig. Daarnaast komt het de leesbaarheid van de code die het nieuwsbericht en de comments in de goede volgorde laat zien ook niet ten goede, want dan moet je met een if in de while van de comments gaan zitten klooien, of je moet de eerste comment ophalen om het nieuwsbericht te laten zien en vervolgens weer terug "seeken" naar het allereerste result om vervolgens toch alle comments te kunnen laten zien.

PV: Growatt MOD5000TL3-XH + 5720wp, WPB: Atlantic Explorer v4 270LC, L/L: MHI SCM 125ZM-S + SRK 50ZS-W + 2x SRK 25ZS-W + SRK 20ZS-W Modbus kWh meter nodig?


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

euh :? Ik snap niet wat je bazelt, zoiets in 1 query doen is imho niet eens een optie :). Maar dat is dan ook niet waar dit codevoorbeeld over ging, namelijk 2x alle informatie ophalen (eerst alles in een keer, en dan nog een keer rij voor rij)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Cartman! schreef op donderdag 26 juni 2008 @ 17:20:
Ook een leuk detail: $oBedrijf is geen object maar een array ;)
$aBedrijf was al bezet, dus dan moet je creatief gaan doen.


Trouwens nog een leuke om mijn post aan te vullen:

PHP:
1
2
3
4
if ( in_array($var, array('blaat')) )
{
   print 'w00t';
}

[ Voor 22% gewijzigd door Michali op 27-06-2008 00:26 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Michali schreef op vrijdag 27 juni 2008 @ 00:24:
Trouwens nog een leuke om mijn post aan te vullen:

PHP:
1
2
3
4
if ( in_array($var, array('blaat')) )
{
   print 'w00t';
}
Opzich is daar niet veel mis mee, true, in deze vorm is het wat raar, maar wellicht stonden er eerst meer items in die array. Zodat je niet een shitload aan expressies krijgt waardoor het onoverzichtelijk wordt.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Dat is ook zo. Maar als je in een pagina een stuk of 10 van dit soort vergelijkingen tegenkomt, dan is er toch wel meer aan de hand. ;)

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
Ik heb nooit ICT gestudeert, maar ik doe wel m'n best om altijd professionele code te schrijven.
- ik weet niet of iemand het herkend -
Als ik mooie goedwerkende code heb, dan begin ik achteraf vaak nog een paar details toe te voegen/tweaken, en dan krijg je vlug dat je propere code er helemaal niet meer proper uit ziet...

Gewoon een vraagje of een pro-programmeur dat herkent?
Ik ga niet heel m'n programma beginnen herschrijven om een detail op te vangen. Ik voeg gewoon een nieuwe variabele ergens in, die de "fout" opvangt.

*True, als je met objecten werkt kun je vaak heel flexible wel nog proffesioneel eraan sleutelen, maar je kunt niet alles in objecten zetten. (allessinds niet zinvol) Wel een reden waarom ik "in love" ben met objecten. (Geeks zijn rare mensen)

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 06:48

Sebazzz

3dp

g4wx3 schreef op vrijdag 27 juni 2008 @ 12:21:
Ik heb nooit ICT gestudeert, maar ik doe wel m'n best om altijd professionele code te schrijven.
- ik weet niet of iemand het herkend -
Als ik mooie goedwerkende code heb, dan begin ik achteraf vaak nog een paar details toe te voegen/tweaken, en dan krijg je vlug dat je propere code er helemaal niet meer proper uit ziet...
(...)
Ik stel voor dat je eens met Microsoft of EA Games moet praten. Hoewel ze het niet zullen toegeven hebben ze precies hetzelfde :) (en ik ook trouwens, soms moet je gewoon vanaf scratch beginnen)

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

Verwijderd

Cartman! schreef op donderdag 26 juni 2008 @ 17:20:
Ook een leuk detail: $oBedrijf is geen object maar een array ;)
Leuk is dat he, een taal waarbij je uit de naam van de variable het type op moet maken :')

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 06:48

Sebazzz

3dp

Verwijderd schreef op vrijdag 27 juni 2008 @ 12:38:
[...]


Leuk is dat he, een taal waarbij je uit de naam van de variable het type op moet maken :')
? Zonder ide haal je in C# ook niet uit de naam het variabeletype ;) maar je punt is duidelijk. Het is wel jammer natuurlijk, en ook een van de grootste nadelen van PHP. Ik vindt het ook jammer dat niet zoals in C# alles een object is. Het is veel handig om $array->pop(); te doen dan array_pop($array);.

Ik denk niet dat het er ooit nog gaat komen, met bepaalde objecten zoals Directory e.d. heeft PHP wel dit object geörienteerde maar daar blijft het ook bij.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Pfff zolang je niet complete spaghetti schrijft heb je echt niet per se Hongaarse notatie in PHP nodig hoor. :z

{signature}


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sebazzz schreef op vrijdag 27 juni 2008 @ 12:43:
Het is veel handig om $array->pop(); te doen dan array_pop($array);
Waarom is dat handiger? Ik zie geen verschil.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Hongaarse notatie, the horror. Goede code heeft dat helemaal niet nodig ;)

Tegenwoordig prefereert men al snel pop_array($array), omdat $array dan alles kan zijn wat aan de benodigde concepten voldoet. Anders moet het perse een object zijn met een member functie pop_array. Object oriented programming maakt plaats voor concept based programming.

[ Voor 65% gewijzigd door Zoijar op 27-06-2008 13:19 ]


Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op vrijdag 27 juni 2008 @ 13:14:

Waarom is dat handiger? Ik zie geen verschil.
Bij $array->pop () kun je de method overloaden als je een derived class gebruikt. Bij het aanroepen van een functie heb je dat voordeel niet. Het is niet mogelijk de array_* functies te overloaden.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op vrijdag 27 juni 2008 @ 13:19:
Bij $array->pop () kun je de method overloaden als je een derived class gebruikt. Bij het aanroepen van een functie heb je dat voordeel niet. Het is niet mogelijk de array_* functies te overloaden.
Functie overloads. (ok, in PHP misschien niet)

[ Voor 4% gewijzigd door Zoijar op 27-06-2008 13:20 ]


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Sebazzz schreef op vrijdag 27 juni 2008 @ 12:43:
[...]

? Zonder ide haal je in C# ook niet uit de naam het variabeletype ;) maar je punt is duidelijk. Het is wel jammer natuurlijk, en ook een van de grootste nadelen van PHP. Ik vindt het ook jammer dat niet zoals in C# alles een object is. Het is veel handig om $array->pop(); te doen dan array_pop($array);.

Ik denk niet dat het er ooit nog gaat komen, met bepaalde objecten zoals Directory e.d. heeft PHP wel dit object geörienteerde maar daar blijft het ook bij.
Je ziet dat bij de mysqli extension er zowel OO als functie-gericht geprogrammeerd kan worden.

Ik dacht dat in php6 het OO principe beter zou worden uitgewerkt, dus hopelijk krijg je dan ook die mogelijkheden (waarbij array_pop alleen het Array object accepteert bijv). Heb je backwards compatibility en makkelijkere methods tot je beschikking.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op vrijdag 27 juni 2008 @ 13:19:
[...]

Bij $array->pop () kun je de method overloaden als je een derived class gebruikt.
Maar niet als je de derived class niet zelf gemaakt hebt, wat bij functies weer wel kan. In PHP kun je dan wel weer geen functies overloaden, maar wel zelf een andere functie maken die iets doet aan de hand van de parameter die wordt meegegeven. Dus geen array_pop(), maar wel een cheatah_pop().

Ik ben er dan ook voorstander van om zo min mogelijk methods toe te voegen aan classes die geen private of protected members van de class gebruiken, op classes die je toch al vrijwel niet ging deriven (zoals arrays of strings).

En met dingen als extension methods zoals in .Net 3(.5?) maakt het geen zak meer uit of je dan pop(array) of array.pop() schrijft - de usage patterns zijn volledig equivalent.

Gelukkig gaat C++0x ook de concepts kant op :9

[ Voor 31% gewijzigd door .oisyn op 27-06-2008 13:38 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

mosymuis schreef op woensdag 18 juni 2008 @ 10:40:
PHP:
1
2
3
4
5
6
7
8
9
10
    $sBedrijfSQL = "select * from tblBedrijf ORDER BY Naam";
    $sBedrijfQuery = mysql_query($sBedrijfSQL);
    while($aBedrijven = mysql_fetch_array($sBedrijfQuery))
    {
        $bedrijfindex = $aBedrijven['ID'];
        $sBedrijfSQLas = "select * from tblBedrijf where ID = '$bedrijfindex'";
        $sBedrijfQueryas = mysql_query($sBedrijfSQLas);
        $oBedrijf = mysql_fetch_assoc($sBedrijfQueryas);
        $aBedrijf[$bedrijfindex] = $oBedrijf;
    }

Wie mij de logica kan uitleggen krijgt een bloemetje }:O
nice ;)

[ Voor 63% gewijzigd door Verwijderd op 27-06-2008 15:18 ]


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Sebazzz schreef op vrijdag 27 juni 2008 @ 12:43:
[...]

? Zonder ide haal je in C# ook niet uit de naam het variabeletype ;)
True, en zonder compiler kun je je computer de code niet eens laten uitvoeren, en zonder computer wordt het uitvoeren van de code überhaupt lastig ;)

Feit is dat verreweg de meeste C# programmeurs gewoon een IDE gebruiken. Gedit of vi gebruiken is niet stoer, maar is gewoon dom :P

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:27
flowerp schreef op vrijdag 27 juni 2008 @ 21:08:
[...]


True, en zonder compiler kun je je computer de code niet eens laten uitvoeren, en zonder computer wordt het uitvoeren van de code überhaupt lastig ;)

Feit is dat verreweg de meeste C# programmeurs gewoon een IDE gebruiken. Gedit of vi gebruiken is niet stoer, maar is gewoon dom :P
Toch ken ik nog steeds iemand die blijft volhouden dat hij het snelst in Java kan programmeren met vim, icm met make-files. Ik heb hem maar voor gek verklaard, want ik kan alleen al met auto-completion zoveel sneller code schrijven... Plus dat je niet continue een browser open moet hebben met alle javadocs erin.

Ik ben iig blij met Eclipse, waarmee je makkelijk kunt zien wat het type van een variabele is en ook of het een locale of member variabele is :) (of welke andere IDE dan ook...)

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

flowerp schreef op vrijdag 27 juni 2008 @ 21:08:
Feit is dat verreweg de meeste C# programmeurs gewoon een IDE gebruiken. Gedit of vi gebruiken is niet stoer, maar is gewoon dom :P
Maak jij grappen over yy3 shift-P ZZ? ;)

Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:27
Zoijar schreef op zaterdag 28 juni 2008 @ 00:37:
[...]

Maak jij grappen over yy3 shift-P ZZ? ;)
viPlugin for Eclipse ;)

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Hehe ;) ok... Ik gebruik eigenlijk voornamelijk visual studio 2008 IDE, en Kate, en soms vi om bv een waarde te veranderen oid.

Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:27
Zoijar schreef op zaterdag 28 juni 2008 @ 00:48:
[...]

Hehe ;) ok... Ik gebruik eigenlijk voornamelijk visual studio 2008 IDE, en Kate, en soms vi om bv een waarde te veranderen oid.
vim editor emulator for Visual Studio :D

Vim kan trouwens wel erg handig zijn voor macro's en dergelijke. Ik heb het zelfs hier gewoon onder windows geïnstalleerd :X

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Marcj schreef op zaterdag 28 juni 2008 @ 00:52:
Vim kan trouwens wel erg handig zijn voor macro's en dergelijke. Ik heb het zelfs hier gewoon onder windows geïnstalleerd :X
Ik werk niet anders dan met (g)vim, ook onder windows :)

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
g4wx3 schreef op vrijdag 27 juni 2008 @ 12:21:
Ik heb nooit ICT gestudeert, maar ik doe wel m'n best om altijd professionele code te schrijven.
- ik weet niet of iemand het herkend -
Als ik mooie goedwerkende code heb, dan begin ik achteraf vaak nog een paar details toe te voegen/tweaken, en dan krijg je vlug dat je propere code er helemaal niet meer proper uit ziet...

Gewoon een vraagje of een pro-programmeur dat herkent?
Ik ga niet heel m'n programma beginnen herschrijven om een detail op te vangen. Ik voeg gewoon een nieuwe variabele ergens in, die de "fout" opvangt.

*True, als je met objecten werkt kun je vaak heel flexible wel nog proffesioneel eraan sleutelen, maar je kunt niet alles in objecten zetten. (allessinds niet zinvol) Wel een reden waarom ik "in love" ben met objecten. (Geeks zijn rare mensen)
Met refactoring kun je je bestaande code zo voorbereiden dat je de wijziging op een nette manier kunt doen. Verdiep je er eens wat meer in. Wat je noemt heet overigens Software rot, en moet je, zeker bij grote applicaties door continu doorontwikkeld worden, zeker serieus nemen.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 13:21

Haan

dotnetter

Vandeweek ook iets lekkers tegengekomen, ik moest een aanpassing maken in een database koppeling, die een collega had geschreven en inmiddels ergens anders is gaan werken. Nu kwam ik dus op een aantal plekken dit tegen:
C#:
1
2
3
4
5
6
7
try
{
   //code
}
catch (Exception e)
{
}

Dat heb ik dus aangepast naar iets dat foutmeldingen naar een logbestand schrijft. Vervolgens krijg ik een log van 40MB.. hmm, vreemd..
Blijkt er dus een fout in de code te zitten die bij ieder record dat wordt ingelezen optreedt en netjes wordt opgevangen door het lege catch blok, waardoor een bepaalde functionaliteit gewoon nooit heeft gewerkt 8)7 al bijna een jaar lang :/
Overigens ook raar dat niemand dat ooit heeft opgemerkt.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Dan zal die functionaliteit niet zo belangrijk zijn geweest, denk ik :D

We are shaping the future


Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Opnieuw een beetje PHP als eigenaarigheidje. Volgens mij toch...
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
if (isset($_REQUEST["login_button"])) {
    $query = "SELECT *
                        FROM gebruiker";
    $result = @mysql_query($query) or die ("Fout bij opzoeken van de gebruiker: ".mysql_error());
    while($detail = mysql_fetch_array($result)) {
        $login_id            = $detail["ID"];
        $gebruikersnaam = $detail["GebruikersNaam"];
        $paswoord            = $detail["Paswoord"];
        $BezoekDatum        = $detail["BezoekDatum"];
        $BezoekUur          = $detail["BezoekUur"];
        $Bezoekaantal    = $detail["Bezoekaantal"];
        if($_REQUEST["login_naam"] == $gebruikersnaam && md5($_REQUEST["paswoord"]) == $paswoord) {
            $foutelogin = "";
            $time = date("d/m/Y - H:i:s");
            $date = date("Y-m-d");
            $time = date("H:i:s");
            $_SESSION["login"] = "1";
            $_SESSION["GebruikersNaam"] = $gebruikersnaam;
            $_SESSION["LoginTime"] = $time;
            $_SESSION["LastLoginDate"] = $BezoekDatum;
            $_SESSION["LastLoginTime"] = $BezoekUur;
            // Bij eerste maal inloggen, doorsturen naar profielpagina. \\
            if ($_SESSION["LastLoginDate"] == "0000-00-00" || $_SESSION["LastLoginDate"] == ""){
                $GLOBALS['firstlogin'] = "1";
            }
            $_SESSION["Gebruiker_ID"] = $login_id;
            $aantal = $Bezoekaantal+1;
            $query = "UPDATE gebruiker SET BezoekDatum = '".$date."',
                                                                         BezoekUur='".$time."',
                                                                         Bezoekaantal='".$aantal."'
                                WHERE ID = '".$login_id."'";
            @mysql_query($query) or die("Fout bij aanpassen van de laatste inlogtijd: ".mysql_error());
            // Voeg actie toe in de log. \\
            $log_id      = $login_id;
            $log_action = "Ingelogd.";
            $log_datum  = date("Y-m-d");
            $log_uur        = date("H:i:s");
            $query_log  = "INSERT INTO log (log_ID , log_gebruiker_ID, log_action, log_datum, log_uur)
                                         VALUES ('', '$log_id', '$log_action', '$log_datum', '$log_uur')";
            @mysql_query($query_log) or die("Fout bij toevoegen van de log gegevens: ".mysql_error());
            break;
        }
        else{
            $foutelogin = "Verkeerde Naam of Paswoord.";
        }
    }
}

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Haan schreef op zaterdag 28 juni 2008 @ 13:43:
Blijkt er dus een fout in de code te zitten die bij ieder record dat wordt ingelezen optreedt en netjes wordt opgevangen door het lege catch blok, waardoor een bepaalde functionaliteit gewoon nooit heeft gewerkt 8)7 al bijna een jaar lang :/
Overigens ook raar dat niemand dat ooit heeft opgemerkt.
Ach ja... ik kom zo nu en dan ook eens code tegen waarvan ik denk "huh? maar dat werkt toch helemaal niet?", wat na verificatie idd ook niet blijkt te werken. En dat is dan code die er sinds Tomb Raider: Legend al in zat. Oh well :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:27
moozzuzz schreef op vrijdag 04 juli 2008 @ 16:23:
Opnieuw een beetje PHP als eigenaarigheidje. Volgens mij toch...
[...]
Wat is een paswoord?

Ik moest hem wel even twee keer doorlezen voordat ik doorhad wat er nu echt gebeurt, maar... :D

Acties:
  • 0 Henk 'm!

  • Webgnome
  • Registratie: Maart 2001
  • Laatst online: 15:05
Marcj schreef op vrijdag 04 juli 2008 @ 16:33:
[...]

Wat is een paswoord?

Ik moest hem wel even twee keer doorlezen voordat ik doorhad wat er nu echt gebeurt, maar... :D
Ik heb hem ook twee keer moeten doorlezen maar ben er nog niet helemaal zeker van. Zit het hem erin dat alle gebruikers worden terug gegeven terwijl je weet van welke gebruik rehet af komt (onnodige loop) of??

Strava | AP | IP | AW


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

Het eerste wat me te binnen schiet, zonder PHP kennis:

- Een @ onderdrukt toch foutmeldingen, inclusief de or die statements?
- Waarom worden er geen datetime velden gebruikt?

En een WTF niet gerelateerd aan PHP:
Je loopt eerst door een hele dataset heen om een gebruiker te updaten? Is het een dermate oude DB dat er geen WHERE gebruikt mag worden?

zo niet, zeg het dan even :D

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

En dan nog het feit dat een string in $foutelogin wordt gebruikt om aan te geven dat het niet goed is gegaan 8)7

[ Voor 6% gewijzigd door .oisyn op 04-07-2008 16:49 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
TeeDee schreef op vrijdag 04 juli 2008 @ 16:40:
Het eerste wat me te binnen schiet, zonder PHP kennis:

- Een @ onderdrukt toch foutmeldingen, inclusief de or die statements?
Nee, die() produceert geen foutmelding.

Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Allemaal juist! Spijtiggenoeg :^S :X

Is inderdaad de login-procedure van een hobby-site waar ik in principe de HTML zou gaan opkuisen, maar ik ga het niet kunnen laten hier en daar mijn *suggesties* te geven...

@Webgnome:
Ik vond het vooral verrassend dat men zoveel onnodige resources verspilt, waar dit lapje code een voorbeeld is... Er zijn maar een 2000 gebruikers maar toch...

@teeDee:
Ik vermoed eigenlijk dat iemand niet wist dat er username like 'xxx' bestond. Ook andere delen vd site hebben nl last van de while.

Ik zal het vanavond ontdekken: dan komen we samen met het 'webteam' om mij de structuur vd website te leren kennen ;)

@ .oisin:
Inderdaad niet allemaal zo van die "gevaarlijke" fouten, maar als je weet dat de core van de website geschreven is door iemand die ook professioneel proggert... (vul zelf aan ;^)

[ Voor 12% gewijzigd door moozzuzz op 04-07-2008 17:02 ]


Acties:
  • 0 Henk 'm!

Verwijderd

moozzuzz schreef op vrijdag 04 juli 2008 @ 16:59:


@teeDee:
Ik vermoed eigenlijk dat iemand niet wist dat er username like 'xxx' bestond. Ook andere delen vd site hebben nl last van de while.
Hoezo 'like'... gewoon WHERE name = 'naam' AND pw = 'pw'...niet moeilijk doen als het ook makkelijk kan ;).

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

Verwijderd schreef op vrijdag 04 juli 2008 @ 17:02:
[...]

Hoezo 'like'... gewoon WHERE name = 'naam' AND pw = 'pw'...niet moeilijk doen als het ook makkelijk kan ;).
En LIKE gebruiken zou een nog grotere WTF zijn dan het overlopen van 2000 gebruikers :)

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Al die assignments zijn ook stom. Lekker 10 dingen assignen die helemaal niet nodig zijn als de username niet overeenkomt. Het 2x $time assignen is ook behoorlijk suf...

En in productie code doe je geen or die(mysql_error())... :X

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Voutloos schreef op vrijdag 04 juli 2008 @ 17:11:
En in productie code doe je geen or die(mysql_error())... :X
Dit is (gelukkig?) dan ook geen productie code ;).

Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
TeeDee schreef op vrijdag 04 juli 2008 @ 17:05:
En LIKE gebruiken zou een nog grotere WTF zijn dan het overlopen van 2000 gebruikers :)
In de voorbeeldcode. Helaas zijn er andere bestanden in het project die veel kleiner zouden zijn met een LIKE.
Verwijderd schreef op vrijdag 04 juli 2008 @ 17:19:
Dit is (gelukkig?) dan ook geen productie code ;).
Hmmz... het is óok geen test/debug-code :D . Dit beest staat toch echt als finale versie online hoor.

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 00:41

TeeDee

CQB 241

moozzuzz schreef op vrijdag 04 juli 2008 @ 18:44:
[...]

In de voorbeeldcode. Helaas zijn er andere bestanden in het project die veel kleiner zouden zijn met een LIKE.

[...]

Hmmz... het is óok geen test/debug-code :D . Dit beest staat toch echt als finale versie online hoor.
Begrijp ik je goed en promoot jij het gebruik van LIKE in een user-check-systeem-ding?

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 06:48

Sebazzz

3dp

TeeDee schreef op vrijdag 04 juli 2008 @ 18:54:
[...]
Begrijp ik je goed en promoot jij het gebruik van LIKE in een user-check-systeem-ding?
Dat wordt leuk als je 5000 records in je database hebt :D

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

Verwijderd

moozzuzz schreef op vrijdag 04 juli 2008 @ 18:44:
[...]

Hmmz... het is óok geen test/debug-code :D . Dit beest staat toch echt als finale versie online hoor.
Je gaf zelf toch aan dat het om een hobby site ging?
Bij 'productie code' denk ik aan bedrijven die je een opdracht geven, waarvoor je betaald wordt etc.

Acties:
  • 0 Henk 'm!

  • g4wx3
  • Registratie: April 2007
  • Laatst online: 11-09 09:49
Als je bang bent voor SQL injection is dit wel *een* manier om dat te voorkomen :D

Uiteraard kun je ook gewoon je invoerveld goed checken vooralleer je een request doet, zoals de meeste. devvers het doen

http://www.softfocus.be/


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

g4wx3 schreef op vrijdag 04 juli 2008 @ 21:49:
Uiteraard kun je ook gewoon je invoerveld goed checken vooralleer je een request doet, zoals de meeste. devvers het doen
Wat valt er te checken aan een username? Als jij "' OR 1" wilt heten dan moet dat gewoon kunnen imho :). Je moet 'm escapen, dat natuurlijk wel.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
.oisyn schreef op vrijdag 04 juli 2008 @ 16:27:
[...]


Ach ja... ik kom zo nu en dan ook eens code tegen waarvan ik denk "huh? maar dat werkt toch helemaal niet?", wat na verificatie idd ook niet blijkt te werken. En dat is dan code die er sinds Tomb Raider: Legend al in zat. Oh well :P
offtopic:
Heb van de week TRL opgepikt voor 6 euro, om mn TR collectie aan te vullen. :) Leuke game, ben er wel op 10 uurtjes spelen al 70% doorheen.


Die try catch constructie heb ik zelf vandaag nog gebruikt. We gebruiken een webservice om gegevens op de homepage van onze klant te plaatsen. Had de oorspronkelijke coder daar geen exception handling omheen gebouwd. Blijkt vandaag die webservice eruit te liggen, en gaf die homepage een exception. ><

De "paniek" was ietsie groter ook nog, omdat de knuppel die het project als laatste onderhanden heeft gehad het voor elkaar heeft gekregen om 2 LLBLGen generated projecten te doen verdwijnen bij het inchecken. Dus, na wat geklooi, (de binaries van die twee projecten van de webserver geplukt en in het project geinclude), heb ik snel even afgevangen met een lege try catch.

Niet echt mooi natuurlijk, maar een paar missende veldjes op de homepage is beter dan geen homepage. Gelukkig was ik toch al bezig met een complete rewrite van die website.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Marcj
  • Registratie: November 2000
  • Laatst online: 11:27
Grijze Vos schreef op zaterdag 05 juli 2008 @ 01:55:
[...]

offtopic:
Heb van de week TRL opgepikt voor 6 euro, om mn TR collectie aan te vullen. :) Leuke game, ben er wel op 10 uurtjes spelen al 70% doorheen.


Die try catch constructie heb ik zelf vandaag nog gebruikt. We gebruiken een webservice om gegevens op de homepage van onze klant te plaatsen. Had de oorspronkelijke coder daar geen exception handling omheen gebouwd. Blijkt vandaag die webservice eruit te liggen, en gaf die homepage een exception. ><

De "paniek" was ietsie groter ook nog, omdat de knuppel die het project als laatste onderhanden heeft gehad het voor elkaar heeft gekregen om 2 LLBLGen generated projecten te doen verdwijnen bij het inchecken. Dus, na wat geklooi, (de binaries van die twee projecten van de webserver geplukt en in het project geinclude), heb ik snel even afgevangen met een lege try catch.

Niet echt mooi natuurlijk, maar een paar missende veldjes op de homepage is beter dan geen homepage. Gelukkig was ik toch al bezig met een complete rewrite van die website.
Waarom dan een leeg catch-block? Zo moeilijk is het niet om de exceptie dan naar een log-bestand weg te schrijven. En je zou toch echt wel een nette foutmelding moeten geven (desnoods een code 500, internal server error).

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
.oisyn schreef op vrijdag 04 juli 2008 @ 16:27:
[...]


Ach ja... ik kom zo nu en dan ook eens code tegen waarvan ik denk "huh? maar dat werkt toch helemaal niet?", wat na verificatie idd ook niet blijkt te werken. En dat is dan code die er sinds Tomb Raider: Legend al in zat. Oh well :P
Een keer een query overgekopieerd, maar vergeten aan te passen, maar het werkte wel :P

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$db->query("SELECT 
                AVG(rating)
            FROM 
                video
            LEFT JOIN 
                rating ON rating.rateid = video.id AND rating.typeid = 3
            WHERE 
                video.userid = '".$user->userid."' 
                AND 
                video.id = '".$id."'
            GROUP BY 
                rating.rateid");
$max = $db->num_rows();

if($max > $config['max_allowed'])
{

Acties:
  • 0 Henk 'm!

  • djiwie
  • Registratie: Februari 2002
  • Laatst online: 11-09 22:26

djiwie

Wie?

Verwijderd schreef op vrijdag 04 juli 2008 @ 19:16:
[...]

Je gaf zelf toch aan dat het om een hobby site ging?
Bij 'productie code' denk ik aan bedrijven die je een opdracht geven, waarvoor je betaald wordt etc.
Ik zie productiecode als software die echt gebruikt wordt door gebruikers, en daar tegenover staat dan de ontwikkelversie waaraan je sleutelt en die nog niet af is. :)

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Veel hobby projecten worden mainstream en de bekenste zijn toch wel PHP, Apache (A patchy webserver (de NSCA webserver was wel veel gebruikt, maar nog niet helemaal af)) en de Linux kernel is denk ik wel het beste voorbeeld. Bedoeld als tegenhanger van Unix Minix vanwege een verhitte discussie met Tanenbaum. Zijn mooiste statement vind ik nog altijd degene uit 1992 'Linux is obsolete' voortkomend uit de discussie microkernels (Minix) vs Monolithic kernels (Linux).

Er zijn een aantal fases waarin een project in kan verkeren waarvan de meeste gebruikte development, beta en productie. Het feit dat een tool door anderen wordt gebruikt betekend niet automatisch dat het geen hobby project meer is. Productie behoort stabiel en geteste code te zijn.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Marcj schreef op zaterdag 05 juli 2008 @ 08:58:
Waarom dan een leeg catch-block? Zo moeilijk is het niet om de exceptie dan naar een log-bestand weg te schrijven. En je zou toch echt wel een nette foutmelding moeten geven (desnoods een code 500, internal server error).
Soms wil je gewoon iets proberen, en als het fout gaat dan is het niet zo erg: dan doe je het gewoon niet. Dat soort dingen wil je niet onnodig een error log mee vullen. Het is niet heel erg netjes, maar ik doe het ook soms. Of bijvoorbeeld dit soort dingen:

C++:
1
2
3
4
5
6
7
8
        try { while (1) {
            ifs >> ts1 >> ts2 >> dummy >> dummy >> nr >> dummy >> x1 >> y1 >> dummy >> dummy >> x2 >> y2 >> dummy;

            if (nr == 2) {
                blobs1.push_back(std::make_pair(x1, y1));
                blobs2.push_back(std::make_pair(x2, y2));
            }
        } } catch (...) {}

Ik wil hier gewoon regels inlezen tot het mis gaat, meestal bij een eof(). Eigenlijk moet ik in die catch iets schrijven als: if (!ifs.eof()) throw; maar dat schiet er vaak bij in...

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Marcj schreef op zaterdag 05 juli 2008 @ 08:58:
[...]


Waarom dan een leeg catch-block? Zo moeilijk is het niet om de exceptie dan naar een log-bestand weg te schrijven. En je zou toch echt wel een nette foutmelding moeten geven (desnoods een code 500, internal server error).
Omdat ik toch niks met dat log zou doen. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Toch vind ik het gebruik van lege catch blokken vaag.

Het haalt de kracht achter try...catch een beetje weg. Het maakt code foutgevoeliger, want voor de gebruiker/tester gaat er niets mis terwijl er eigenlijk continue code faalt en daar geen melding van geeft door het lege catch blok.

Daarom: altijd even een logje, debug- of foutmelding weergeven is mijn mening.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Juist. Al was het maar voor het testtraject...

{signature}


Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:23

Robtimus

me Robtimus no like you

En zelfs al wil je geen logging, zet er dan een stukje commentaar in WAAROM je de exceptie negeert.

Zelf heb ik in Eclipse ingesteld dat hij moet waarschuwen als er lege bodies zijn. Dan ben je wel genoodzaakt er iets mee te doen, al is het maar om de warning kwijt te raken ;)

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

Verwijderd

IceManX schreef op maandag 07 juli 2008 @ 13:04:
En zelfs al wil je geen logging, zet er dan een stukje commentaar in WAAROM je de exceptie negeert.

Zelf heb ik in Eclipse ingesteld dat hij moet waarschuwen als er lege bodies zijn. Dan ben je wel genoodzaakt er iets mee te doen, al is het maar om de warning kwijt te raken ;)
Inderdaad, ReSharper (plugin voor Visual Studio, C#) geeft ook meldingen van lege Catch blokken...echt netjes staat het niet nee. Komt gewoon op het onderdrukken van exceptions neer :o.

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op maandag 07 juli 2008 @ 13:45:
Inderdaad, ReSharper (plugin voor Visual Studio, C#) geeft ook meldingen van lege Catch blokken...echt netjes staat het niet nee. Komt gewoon op het onderdrukken van exceptions neer :o.
En onderdrukken van excepties komt wel vaker voor, en soms ook met goede redenen dat het niet eens een debug message waard is. Vaak doe ik dan iets als:
Java:
1
2
3
4
5
6
7
8
9
InputStream in = null;
try {
  //Stream creation and reading
} catch(IOException e){
   LOG.warn("log me", e);
} finally {
  try{if(in != null) in.close();}
  catch(IOException ignorable) {}
}

Prima leesbaar en je hoeft er toch niet meer commentaar kwijt.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Resource-release-methoden die een exception kunnen gooien: dat geeft een C++-er koude rillingen. ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Zoijar schreef op maandag 07 juli 2008 @ 16:04:
Resource-release-methoden die een exception kunnen gooien: dat geeft een C++-er koude rillingen. ;)
Deze javanist ook hoor ;)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op maandag 07 juli 2008 @ 16:04:
Resource-release-methoden die een exception kunnen gooien: dat geeft een C++-er koude rillingen. ;)
Weleens een ongeopende std::fstream proberen te sluiten met close() terwijl exceptions op de stream aanstonden? :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ja, het is idd nooit echt netjes, maar in C++ is het meteen program terminate zodra een destructor een exception throwed... en laten dat nu juist de momenten zijn waarin je resources op wilt ruimen. Dat kan in Java natuurlijk ook fout gaan als je die exception niet afvangt, maar in ieder geval zie je nog waar het fout gaat op een hoger niveau.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Uiteraard, en aangezien C++ geen finally kent en wél destructors heeft is het natuurlijk sowieso aan te raden om een stream te laten sluiten middels z'n destructor (die de exception van de close() dan onderdrukt, wat weer mooi in de context van deze subdiscussie past ;)).

Neemt niet weg dat ik onlangs eens raar stond te kijken toen ik eens een manual close() deed in een catch handler om de file opnieuw te openen :P

[ Voor 5% gewijzigd door .oisyn op 07-07-2008 16:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op maandag 07 juli 2008 @ 16:09:
Weleens een ongeopende std::fstream proberen te sluiten met close() terwijl exceptions op de stream aanstonden? :P
Ik close die dingen nooit; ik ga ervan uit dat de dtor dat veilig doet...

Maar dit is idd enge code:
C++:
1
2
3
4
5
6
7
8
9
10
11
class X {
public:
    std::fstream fs;

    X() {
        fs.exceptions(std::ios::failbit | std::ios::badbit | std::ios::eofbit);
    }
    ~X() {
        fs.close();
    }
};


Wist ik eerlijk gezegd niet. Verbazingwekkend.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Idd. Je zou bijna kunnen argueën dat destructors altijd een impliciete throw() spec moeten hebben.

Hmm nu vraag ik me ineens af, stel je specificeert expliciet een lege throw spec, geldt die dan ook voor de members van T, die feitelijk pas worden gedestruct nadat de code in de dtor van T is uitgevoerd?


.edit: nvm, deze gedachtenkronkel slaat sowieso nergens op. Een lege throw spec eet geen exceptions, hij zorgt er alleen voor dat unexpected() wordt aangeroepen zodra er een exception optreedt.

[ Voor 76% gewijzigd door .oisyn op 07-07-2008 16:31 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op maandag 07 juli 2008 @ 16:28:
.edit: nvm, deze gedachtenkronkel slaat sowieso nergens op. Een lege throw spec eet geen exceptions, hij zorgt er alleen voor dat unexpected() wordt aangeroepen zodra er een exception optreedt.
Ja, unexpected() of terminate() is ook weinig feitelijk verschil. Dus eigenlijk bestaat die restrictie al, min of meer.

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Niet programmeren, wel scripten, maar ik vond het wel leuk om hierbij te zetten:
Vroeger deed ik in Javascript het volgende:
JavaScript:
1
<div onmouseover="this.style.cursor='hand';" onmouseout="this.style.cursor='default';"></div>

:+

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

Verwijderd

Zoijar schreef op maandag 07 juli 2008 @ 16:13:
... in C++ is het meteen program terminate zodra een destructor een exception throwed...
Hoe kom je daar nou bij? Je kunt op zich probleemloos een exception throwen in een destructor, het zou m.i. zelfs tragisch zijn indien dat niet mogelijk zou zijn.

Wat fout afloopt is het throwen van een exception tijdens de afhandeling van een andere exception. Voorbeeld:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include  <iostream>

class   T
{
public:
    ~T (void) { throw 0; }
};


int main (void)
{
    try
    {
        T t[1];
    }
    catch (...)
    {
        std::cout << "Exception caught" << std::endl;
    }

    std::cout << "End of program." << std::endl;

    return 0;
}

In dit voorbeeld wordt de exception keurig afgevangen. Maar verander op regel 14: '[1]' in '[2]', en je krijgt - zoals verwacht - een abnormal program termination.

Een voorbeeld waarmee het probleem van potentieel throwen tijdens de afhandeling van een user-exception geïllustreerd kan worden, is het volgende (wrapper-class rond fopen() / fwrite() / fclose()):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class   T
{
    FILE * m_pcOutFile;

public:
    T (const char *);
    ~T (void);
    void VWrite (const char *);
};


// Constructor
T::T (const char * pszPath)
: m_pcOutFile (fopen (pszPath, "wb"))
{
    if (m_pcOutFile == NULL)
        throw 0;
}


// Destructor
T::~T (void)
{
    if (fclose (m_pcOutFile) != 0)
        throw 0;
}


// Writer
void
T::VWrite (const char * pszData)
{
    if (fwrite (pszData, strlen(pszData), 1, m_pcOutFile) != 1)
        throw 0;    // disk full? drive lost? fs currupt? whatever...
}

int main (void)
{
    try
    {
        T t ("test");

        t.VWrite ("Hello world");
    }
    catch (...)
    {
        std::cout << "Exception caught" << std::endl;
    }

    std::cout << "End of program." << std::endl;

    return 0;
}

Indien tijdens uitvoering van regel 43 een exception gethrowd wordt, dan zou de situatie kunnen ontstaan dat er tijdens de afhandeling daarvan door de code op regel 25 een tweede exception gethrowd wordt, met een onbedoelde program termination tot gevolg.

Om dit probleem te omzeilen, gebruik ik in dit soort situaties vaak exceptions afgeleid van het volgende type:
code:
1
2
3
4
5
6
7
8
9
10
11
class   E
{
    static  int  s_unCnt;

public:
     E (void) { ++s_unCnt; }
    ~E (void) { --s_unCnt; }
    static  int  BCanThrow (void) { s_unCnt == 0; }
};

int  E::s_unCnt = 0;


Regel 25 in het tweede code snipplet wordt dan vervangen door
C++:
1
    if (E::BCanThrow()) throw E();

Resultaat bij konsekwent gebruik is dat je niet de afhandeling van je eigen gethrowde exception in de weg gaat zitten.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op dinsdag 08 juli 2008 @ 10:51:
Hoe kom je daar nou bij? Je kunt op zich probleemloos een exception throwen in een destructor, het zou m.i. zelfs tragisch zijn indien dat niet mogelijk zou zijn.

Wat fout afloopt is het throwen van een exception tijdens de afhandeling van een andere exception. Voorbeeld:
Ja, ok, dat is zo.
Om dit probleem te omzeilen, gebruik ik in dit soort situaties vaak exceptions afgeleid van het volgende type:
Dit is imho een slechtprogrammeervoorbeeld. Dit gaat hard mis indien iets toevallig een keer een std::exception throwed, of gewoon een heel eigen type in een library oid. Het gaat mis bij geheugen allocatie op de heap, vooral bij arrays op de heap, en mensen verwachten dat een dtor niet throwed. Ik snap ook niet waarom mensen toch altijd maar weer per se ingewikkelde constructies willen maken om toch exceptions in een dtor te throwen.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op dinsdag 08 juli 2008 @ 10:51:
[...]

Hoe kom je daar nou bij? Je kunt op zich probleemloos een exception throwen in een destructor, het zou m.i. zelfs tragisch zijn indien dat niet mogelijk zou zijn.
Tragisch? Destructors should never throw! Het geeft meer problemen dan voordelen. Als je een delete aanroept op een object die throwt in z'n destructor, dan leak je bijvoorbeeld geheugen.
Regel 25 in het tweede code snipplet wordt dan vervangen door
C++:
1
    if (E::BCanThrow()) throw E();
Met als gevolg dat als je jouw progamma merged met die van een ander die iets soortgelijks doet, dan werkt het al niet meer. Kun je beter uncaught_exception() gebruiken. Nog beter throw je gewoon niet in de destructor - het object is toch weg dus over het algemeen ben je niet eens geïnteresseerd in een eventuele foutmelding.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

nPrecies. Draai dit maar eens voor de lol
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class T{
public:
    T() {}
    ~T() {throw 0;}
    int data[1024];
};

int main(int argc, char* argv[]) {
    
    
    while (1) {
        try {
            T* t = new T();
            delete t;
        } catch (...) {}
    }
return 0;
}

Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op dinsdag 08 juli 2008 @ 11:23:
[...]

Tragisch? Destructors should never throw! Het geeft meer problemen dan voordelen. Als je een delete aanroept op een object die throwt in z'n destructor, dan leak je bijvoorbeeld geheugen.
Goto's are evil! ;)

Dus: oneens. Als ik in een destructor een exception throw, dan heb ik nagedacht over de consequenties, en is het dus een zeer bewuste keuze. Zie ook verderop.
[...]

Met als gevolg dat als je jouw progamma merged met die van een ander die iets soortgelijks doet, dan werkt het al niet meer. Kun je beter uncaught_exception() gebruiken. Nog beter throw je gewoon niet in de destructor - het object is toch weg dus over het algemeen ben je niet eens geïnteresseerd in een eventuele foutmelding.
Uiteraard, je hebt helemaal gelijk. Echter, het ging mij in mijn vorige post om een strategie. Dat die strategie niet per definitie braindead universeel kompleet safe bruikbaar is, is imho géén reden om die strategie a priori af te branden. Wel eens van 'het kind met het badwater weggooien' gehoord? Niet elk programma gebruikt meer dan één base-type exception, dus het is niet per definitie onveilig.

Het leek ondergetekende dermate triviaal dat wanneer je zo'n strategie gebruikt naast andere exceptions, je die andere exceptions ook af dient te vangen, dat ik dat in mijn vorige post niet heb meegenomen. Ik realiseer me dat ik dat voor de duidelijkheid beter wel had kunnen vermelden.

Bedenk echter wel terdege dat wanneer jij in een destructor van een open/close-type wrapper class een fclose() doet, en die mislukt - bijvoorbeeld ten gevolge van een disk-full situatie, en jij gooit geen exception, zet geen globale flag, en doet niet iets vergelijkbaars, dan zul jij bijvoorbeeld een tijdens de fclose() mislukte flush niet op het moment van optreden, of mogelijk nog veel erger: zelfs helemaal niet, signaleren. De enige mogelijkheid die jij dan hebt, is een fclose() expliciet aanroepen via een public member. Waarmee je het belangrijkste idee van de class, namelijk het tijdens de afhandeling van een exception impliciet afsluiten van de file, onmogelijk maakt. En je never zeker weet of je na de close niet met een corrupte - want te korte - file zit. De direkte implicatie is dat óf je class niet exception-safe is, óf je gaat buiten je class knoeien om een tekortkoming in je strategie recht te knutselen. En dat vind ik op mijn beurt in beginsel geen goed idee, omdat je dan het idee van encapsulation overboord gooit...Conditional-throwing vind ik dan absoluut een geschikt idee. Uiteraard is het wel noodzakelijk dat je erg goed nadenkt over je exceptions model, om op het juiste moment een geschikte recovery te kunnen uitvoeren.

En wat dat memory-leak betreft:
1) je hóeft een object niet met new te alloceren, je kunt het ook op de stack zetten;
2) als je het zou willlen: het is perfect mogelijk een simpele GC te maken die dat bewuste potentiële leak op een geschikt moment alsnog opruimt. Maar ik denk dat de diskussie daarover buiten de scope van dit topic valt.

Ter illustratie: ik heb hier bijvoorbeeld een lib liggen met wrappers om een flink deel van de WIN32 API. ELKE zo ongeveer niet OS-dodelijke exception die ik überhaupt af wil vangen, vang ik ook af, en wrap die om een van mijn eigen exception types. Een flink aantal van die wrappers zijn classes die kunnen throwen in hun destructors, en maken gebruik van zo'n throw-counter. Dit werkt naar volle tevredenheid, en is simpelweg veilig op de manier waarop het hier gebruikt wordt. Als een applicatie-programmeur dan besluit e.e.a. te mixen met andere libraries die andere exception-types kunnen throwen, dan is het logisch dat hij/zij daar inderdaad rekening mee zal moeten houden. Maar dat maakt mijn library nog niet meteen onbruikbaar of zelfs evil! ;) .

Acties:
  • 0 Henk 'm!

Verwijderd

Zoijar schreef op dinsdag 08 juli 2008 @ 11:17:
Dit gaat hard mis indien iets toevallig een keer een std::exception throwed
Ik neem aan dat je bedoelt:
Dit gaat hard mis indien regel 25 een exception gooit terwijl iets toevallig een keer een std::exception heeft gethrowed die op dat moment afgehandeld wordt
Anders is er namelijk helemaal niets aan de hand.

Ter illustratie van mijn manier van werken, wil ik een analogie geven: je gaat een hovenier toch ook niet verbieden een kettingzaag te gebruiken omdat zo'n stuk gereedschap bij verkeerd gebruik forse problemen op kan leveren? Nee, zo'n ding kan uitermate nuttig zijn. Wel houd je natuurlijk terdege rekening met de eigenschappen ervan.

Of C verbieden omdat je het volgende kan doen:
C:
1
2
3
4
5
char * F (void)
{
    char  buf[32];
    return buf;
}

Het feit dat je zoiets kunt doen, maakt het returnen van een char * vanuit een functie toch niet meteen per definitie een onbruikbaar concept? Of zelfs C onbruikbaar?
mensen verwachten dat een dtor niet throwed.
Ik denk dat de volgende vraag belangrijk is: welke mensen bedoel je eigenlijk?

Vergeet niet dat C++ (mede vanwege de basis 'C') van origine een taal is die niet als doelstelling heeft om probleemloos door elke beginner met succes gebruikt te kunnen worden in grotere projecten, maar een taal voor programmeurs met ervaring - die dus weten waar ze mee bezig zijn. Ik denk te kunnen stellen dat mensen die professioneel met C++ bezig zijn, zich hiervan bewust (dienen te) zijn. En dus wel degelijk moeten kunnen verwachten dat dit soort zaken kunnen spelen. En mede daarom defensief programmeren.

Nogmaals: mijn punt is dat imho dit soort dingen niet meteen afgebrand moet worden omdat niet elke programmeur meteen ziet dat het problemen op kan leveren. Al je dat gaat doen, dan kun je bijvoorbeeld net zo goed het singleton-pattern overboord gooien, omdat er mt-omgevingen zijn die geen atomaire counter set / increment / decrement hebben, of niet 100% threadsafe critical sections of zelfs semaforen kunnen creëren... Absoluut met alle respect: je gaat ook niet als overheid een wet uitbrengen die het vermogen van een kettingzaag limiteert, omdat er ook niet-profs mee werken?

Terzijde: zo ingewikkeld is een enkele uitstekend gedocumenteerde persistent flag toch niet?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik geloof dat ik should zei, niet must. Ben je het er dan nog steeds mee oneens?
Bedenk echter wel terdege dat wanneer jij in een destructor van een open/close-type wrapper class een fclose() doet, en die mislukt - bijvoorbeeld ten gevolge van een disk-full situatie, en jij gooit geen exception, zet geen globale flag, en doet niet iets vergelijkbaars, dan zul jij bijvoorbeeld een tijdens de fclose() mislukte flush niet op het moment van optreden, of mogelijk nog veel erger: zelfs helemaal niet, signaleren.
Niemand had het erover dat je je foutafhandeling niet fatsoenlijk hoeft te implementeren, in destructors of anderzijds. De discussie ging om het gooien van exceptions vanuit de destructor.

Je voorbeeld is wel aardig. Want wat ga je nu doen met de kennis dat T een exception heeft gegooid tijdens het sluiten van de stream? T is weg. De data is weg. Je kan het alleen ter kennisgeving aannemen. Als je het dus in de eerste plaats al fatsoenlijk af wilt kunnen handelen, dan zul je moeten zorgen dat je een flush doet voordat je object gedestruct wordt, zodat je passende maatregelen kan nemen. En als je object wordt gedestruct ten gevolgen van een andere exceptie, waardoor je het throwen dan maar laat, dan gaat de fout alsnog aan je neus voorbij, waardoor je dus sowieso min of meer gedwongen wordt om iets meer te doen in de destructor (of daarvoor) dan het gooien van een exception, met als gevolg dat die exception in zichzelf al vrij nutteloos wordt.

Het is imho al een beetje een broken concept dat je nog allemaal zinvolle dingen gaat zitten doen in opruim-code, waar je dan evt. nog op wilt reageren.
1) je hóeft een object niet met new te alloceren, je kunt het ook op de stack zetten;
Echter als ik jouw object als member van mijn object definieer, ik mijn object ook ineens niet meer kan newen zonder potentieel te leaken. Het ripplet dus nogal door in je hele applicatie.
2) als je het zou willlen: het is perfect mogelijk een simpele GC te maken die dat bewuste potentiële leak op een geschikt moment alsnog opruimt. Maar ik denk dat de diskussie daarover buiten de scope van dit topic valt.
Perfect zou ik het niet willen noemen, en dat het mogelijk is wil nog niet meteen zeggen dat dat dan ook maar een goed idee is :).
Ter illustratie: ik heb hier bijvoorbeeld een lib liggen met wrappers om een flink deel van de WIN32 API. ELKE zo ongeveer niet OS-dodelijke exception die ik überhaupt af wil vangen, vang ik ook af, en wrap die om een van mijn eigen exception types. Een flink aantal van die wrappers zijn classes die kunnen throwen in hun destructors, en maken gebruik van zo'n throw-counter. Dit werkt naar volle tevredenheid, en is simpelweg veilig op de manier waarop het hier gebruikt wordt. Als een applicatie-programmeur dan besluit e.e.a. te mixen met andere libraries die andere exception-types kunnen throwen, dan is het logisch dat hij/zij daar inderdaad rekening mee zal moeten houden. Maar dat maakt mijn library nog niet meteen onbruikbaar of zelfs evil! ;) .
Ik snap nog steeds niet waarom je je eigen counter verdedigt terwijl het gebruik van de standaard functie uncaught_exception() het wél "veilig" maakt met andere libraries. Naast het feit dat ik je design gewoon flawed vind, of het voor jou nou werkt of niet :)
Ik denk te kunnen stellen dat mensen die professioneel met C++ bezig zijn, zich hiervan bewust (dienen te) zijn. En dus wel degelijk moeten kunnen verwachten dat dit soort zaken kunnen spelen. En mede daarom defensief programmeren.
Het grappige hierbij is wel dat het gros van de professionele C++ programmeurs, inclusief een aantal in het C++ committee, van mening zijn dat een dtor nooit moet throwen (over defensief programmeren gesproken :D) en dat de standaard dat ook zou moeten verbieden. Om Herb Sutter te quoten:
I understand that some people might feel that "a failed dtor during stack unwinding is preferable in certain cases" (e.g., when recovery can be done beyond the scope of the program), but the problem is "says who?" It is the application program that should be able to decide whether or not such semantics are correct for it, and the problem here is that with the status quo a program cannot defend itself against a std::terminate() — period. The lower-level code makes the decision for everyone. In the original example, the mere existence of an XY object puts at risk every program that uses it, whether std::terminate() makes sense for that program or not, and there is no way for a program to protect itself.

That the "it's okay if the process goes south should a rare combination of things happen" decision should be made by lower-level code (e.g., X dtor) for all apps that use it, and which doesn't even understand the context of any of the hundreds of apps that use it, just cannot be correct.

[ Voor 17% gewijzigd door .oisyn op 08-07-2008 22:26 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
.oisyn schreef op dinsdag 08 juli 2008 @ 14:29:
Ik snap nog steeds niet waarom je je eigen counter verdedigt terwijl het gebruik van de standaard functie uncaught_exception() het wél "veilig" maakt met andere libraries.
Je zet veilig al tussen aanhalingstekens maar ik wil toch even duidelijk maken dat uncaught_exception() ook nogal wat haken en ogen heeft.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het morele verhaal stond al in mijn post, het unsound verhaal had ik idd nog niet eens aan gedacht, da's wel een goede. hij lost dat probleem ook niet op met de exception counter, dus in die context is uncaught_exception() een beter (maar imho nog altijd geen goed) idee.

Er is overigens ook een case waarin uncaught_exception() en een exception counter zoals geïmplementeerd door hij weldegelijk verschillen:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    try
    {
        // code die een E throwt
    }
    catch(E & e)
    {
        /*
            uncaught_exception() geeft hier false, een dtor mag hier throwen.
            E::BCanThrow() geeft hier echter ook false, want 'e' is nog niet
            gedestruct dus de counter staat nog niet op 0.
        */
    }
}


Dit hele "de ene keer wel, maar soms ook niet" maakt het imho een beetje warrig en, idd, unsound. Beter throw je gewoon helemaal niet vanuit destructors.

[ Voor 61% gewijzigd door .oisyn op 08-07-2008 22:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op dinsdag 08 juli 2008 @ 14:20:
Ik neem aan dat je bedoelt:

Anders is er namelijk helemaal niets aan de hand.
Nou, ik bedoelde eigenlijk dit:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class E {
public:
    static int count;
    E() {++count; std::cout << "E() count = " << count << std::endl;}
    ~E() {--count; std::cout << "~E() count = " << count << std::endl;}

    E(const E& src) {count++;}
    E& operator=(const E& src) {}

    static bool canThrow() { 
        std::cout << "canthrow = " << count << std::endl;
        return count == 0;
    }
};
int E::count = 0;

class T{
public:
    T() {}
    ~T() {
        if (E::canThrow()) throw E();
    }
    int data[1024];
};

int main(int argc, char* argv[]) {
    try {
        T t; // use your object

        // do stuff
        
        // oops, something goes wrong in my code
        throw std::exception("Just a minor issue; ignore");

    } catch (...) {
        std::cout << "Exception caught" << std::endl;
    }
    std::cout << "Program ends" << std::endl;
    return 0;

dat terminate.
Ik denk dat de volgende vraag belangrijk is: welke mensen bedoel je eigenlijk?
Zo'n beetje de gehele C++ community. Throwing dtor is not-done. Het geeft te veel problemen, terwijl het niets oplevert. Je weet namelijk nog steeds niets met jouw methode: waren het 1 of 2 exceptions?
Vergeet niet dat C++ (mede vanwege de basis 'C') van origine een taal is die niet als doelstelling heeft om probleemloos door elke beginner met succes gebruikt te kunnen worden in grotere projecten, maar een taal voor programmeurs met ervaring - die dus weten waar ze mee bezig zijn. Ik denk te kunnen stellen dat mensen die professioneel met C++ bezig zijn, zich hiervan bewust (dienen te) zijn. En dus wel degelijk moeten kunnen verwachten dat dit soort zaken kunnen spelen. En mede daarom defensief programmeren.
Precies. En daarom kan je dus wel throwen uit een dtor, maar zou je het nooit moeten doen.
Terzijde: zo ingewikkeld is een enkele uitstekend gedocumenteerde persistent flag toch niet?
Het kan op zo veel manieren mis gaan dat het het niet waard is. Wat is dat nou voor een restrictie dat ik je objecten niet op de heap mag alloceren? Je kan wel een garbage-collector schrijven (omdat je uit een dtor wilt throwen...) maar dan nog resulteert dit:
C++:
1
2
T* t = new T[5];
delete[] t;

met jouw systeem in undefined behaviour. Er is geen garantie hoeveel objecten er hier destroyed (dtor aangeroepen) worden.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar: dat laatste voorbeeld klopt niet helemaal. De T's die tot dan zijn geconstruct worden (in omgekeerde volgorde) ook weer gedestruct. Ookal throwt een van de T's tijdens destruction een exception :). Het geheugen ben je echter wel kwijt.

.edit: nee, ik vergis me. Het is weldegelijk UB.

15.2
15.2 Constructors and destructors
1 As control passes from a throw-expression to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.

2 An object that is partially constructed or partially destroyed will have destructors executed for all of its fully constructed subobjects, that is, for subobjects for which the constructor has completed execution and the destructor has not yet begun execution. Should a constructor for an element of an automatic array throw an exception, only the constructed elements of that array will be destroyed. If the object or array was allocated in a new-expression, the matching deallocation function (3.7.3.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.

3 The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called “stack unwinding.” [Note: If a destructor called during stack unwinding exits with an exception, terminate is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor. —end note]
Het staat er niet bij wat er gebeurt bij een exception vanuit een dtor in een array. Dus UB.

[ Voor 88% gewijzigd door .oisyn op 08-07-2008 15:31 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ja, het is UB. Dan kan je ook bedenken aan hoe de code er meestal uit ziet. Er wordt een destroy heap array call gemaakt. Die implementatie gaat, waarschijnlijk, alle elementen af, roept de dtor aan op elk element, en geeft aan het einde het heap geheugen vrij. Als nu een van de dtors throwed, dan zit het er dik in dat de rest niet meer afgehandeld wordt. Maar er is geen traversal ordening opgelegd, dus weet je nooit welke dtors je implementatie nou al aangeroepen heeft. Met 1 element op de heap is het wel gegarandeerd dat die ene dtor wordt aangeroepen, maar vervolgens blijft de geheugen-opruim-stap undefined.

Na dit te typen bedenk ik me nog een flaw: je mag die throwing dtor objecten ook niet in STL containers opslaan. De erase calls van de STL gebruiken allocators, en die ruimen objecten op door expliciet de dtor aan te roepen, en dan het geheugen te dealloceren. Als die dtor throwed gaat het ook mis.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dan kan je ook bedenken aan hoe de code er meestal uit ziet. [...]
Je argumenten kun je ook toepassen wanneer een ctor throwt in een array; daar is het echter wel gewoon goed geregeld (het destruct alle geconstructe elementen en geeft het geheugen weer vrij). Ook moet de delete sowieso weten in welke volgorde de objecten zijn geconstruct, omdat hij ze in omgekeerde volgorde moet destructen. Hij kan dus exceptions vangen tijdens destructen, en bij een exception de rest nog destructen.

Er is ook een defect report over (niet zozeer over de array case, maar wel het deleten van een object met throwing dtor): http://www.open-std.org/j.../docs/cwg_active.html#265. Het probleem is niet zozeer dat het niet kan, maar dat het een performance-implicatie heeft omdat je niet altijd van tevoren kan weten of een dtor throwt (waardoor je in essentie altijd een impliciete try/catch om elke delete krijgt), waardoor je een performance penalty betaalt voor mogelijke situaties die sowieso al bad practice zijn.

[ Voor 12% gewijzigd door .oisyn op 08-07-2008 20:50 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op dinsdag 08 juli 2008 @ 20:26:
Je argumenten kun je ook toepassen wanneer een ctor throwt in een array; daar is het echter wel gewoon goed geregeld (het destruct alle geconstructe elementen en geeft het geheugen weer vrij).
Logisch gezien is het wel anders. Bij construction kan je gewoon alles netjes constructen en als er een fout optreedt dan destruct je alles dat je al had opgebouwd (moet uiteraard niet je dtor throwen tijdens het opruimen...). Dat kan je vrij simpel implementeren. Bij destruction zou je een eventuele fout tijdelijk op moeten slaan, verder gaan met destructen, eventuele andere fouten ook op moeten slaan, en dan aan het einde kiezen welke van die fouten je naar je applicatie throwed. Dat werkt niet makkelijk. (ie. destruction zou meerdere exception kunnen/moeten throwen, terwijl constructie er altijd maximaal eentje kan throwen) Plus dat die checks idd tijd kosten, zoals jij net zei.

[ Voor 6% gewijzigd door Zoijar op 08-07-2008 20:41 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Bij destruction zou je een eventuele fout tijdelijk op moeten slaan, verder gaan met destructen, eventuele andere fouten ook op moeten slaan, en dan aan het einde kiezen welke van die fouten je naar je applicatie throwed
Onzin natuurlijk, hij hoeft maar 1 exception te bewaren. Bij de volgende krijg je toch een terminate()
Dus in de vorm van:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
T * t = new T[5];
int i;
try
{
    for (i = 0; i < 5; i++)
        t[i].~T();
    operator delete[](t);
}
catch(...)
{
    for (i++; i < 5; i++)
        t[i].~T();
    operator delete[](t);
    throw;
}


(met natuurlijk het subtiele verschil dat uncaught_exception() in het catch blok wel true moet zijn en nog een exception zorgt voor een terminate())

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ja, ok, maar als er dus een tweede komt krijg je nog steeds een terminate die je niet verwacht. Plus dat je dan nog steeds niet weet welke er zijn aangeroepen. Niet echt een geweldige oplossing. Ik denk dat het vanwege deze problemen UB is; laat een implementatie maar iets doen, het is toch binnen korte tijd crash&burn ;)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Goed, bottom line:
.oisyn schreef op dinsdag 08 juli 2008 @ 11:23:
Destructors should never throw!
;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Jammer, maar met name vanwege je bovenstaande post laat ik het hierbij. De reply die ik aan het voorbereiden was, besloeg al tegen de 300 regels, maar ik begin te vermoeden dat verdere uitwerking en het posten ervan vanwege een fundamenteel perceptie-verschil dat verder gaat dan het onderwerp van diskussie, niet bijster zinvol is. Hiermee is meteen mijn probleem dat ik na die post wel eens als topic-kaper gezien zou kunnen worden, verdwenen. Iig bedankt voor de moeite die jij en Zoijar genomen hebben, en tot een volgende keer dan maar.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Eentje van mezelf, omdat 1) zelfspot me niet vreemd is en 2) ik me hier helemaal gek mee gemaakt heb:

Java:
1
2
3
4
5
6
7
            if(masterEntry.getKey().equals(slaveEntry.getKey()))
            {
                if(!modifiedInRange(masterEntry.getModified(), slaveEntry.getModified(), timeLimit));
                { 
                    System.out.println("> " + masterEntry.getKey());
                }
            }

https://niels.nu


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

:D
Dat je compiler geen warning geeft vind ik wel een beetje suf.

Ik kwam ooit zo'n constructie tegen:
C++:
1
2
3
4
5
if (conditie1)
    if (conditie2)
        doeIets();;
    else
        doeIetsAnders();

8)7

.edit: nee, m'n geheugen klopt niet, het was anders. Dit compileert sowieso niet.

[ Voor 70% gewijzigd door .oisyn op 11-07-2008 16:16 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Ik zie 'm niet. :X

[edit]
De punt-komma na de if() natuurlijk. :P

[ Voor 58% gewijzigd door AtleX op 11-07-2008 16:06 ]

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • majoh
  • Registratie: September 2001
  • Laatst online: 08:51

majoh

ᕦ(ò_óˇ)ᕤ

is het de ';' achter de if?

Acties:
  • 0 Henk 'm!

  • WVL_KsZeN
  • Registratie: Oktober 2002
  • Laatst online: 13:19
; na de 2e if?

/me heeft eindelijk ook een icoontje.. woef.. boeien..


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Overigens is er ook net een topic met deze fout gesloten. :+ O-)

{signature}


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op dinsdag 08 juli 2008 @ 23:26:
Jammer, maar met name vanwege je bovenstaande post laat ik het hierbij. De reply die ik aan het voorbereiden was, besloeg al tegen de 300 regels, maar ik begin te vermoeden dat verdere uitwerking en het posten ervan vanwege een fundamenteel perceptie-verschil dat verder gaat dan het onderwerp van diskussie, niet bijster zinvol is. Hiermee is meteen mijn probleem dat ik na die post wel eens als topic-kaper gezien zou kunnen worden, verdwenen. Iig bedankt voor de moeite die jij en Zoijar genomen hebben, en tot een volgende keer dan maar.
Ik denk heus wel na over alle suggesties hoor; het is niet zo dat ik bij voorbaat al zeker van m'n gelijk ben. Ik heb je code zelfs compiled en getest, maar het werkt gewoon niet goed. Tot nu toe heb ik nog steeds geen goed argument gezien om throwing dtors te gebruiken, en wel op een veilige manier. Ik raad je daarom ook nog steeds aan die code die je postte niet te gebruiken: het is niet veilig.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
.oisyn schreef op vrijdag 11 juli 2008 @ 16:02:
:D
Dat je compiler geen warning geeft vind ik wel een beetje suf.
Dat vond ik dus ook. Op 1920x1200 zie je die puntkomma's nauwelijks. Pas toen ik dat stuk code teruggebracht had naar if(false); {} en hij nog steeds het stuk tussen accolades uitvoerde viel me opeens op dat er een puntkomma stond. Een collega zag 'em ook niet.

Tja. Vrijdagen :D

https://niels.nu

Pagina: 1 ... 7 ... 11 Laatste

Dit topic is gesloten.

Let op:
Uiteraard is het in dit topic niet de bedoeling dat andere users en/of topics aangehaald worden om ze voor gek te zetten. Lachen om je eigen code, of over dingen die je "wel eens tegengekomen bent" is prima, maar hou het onderling netjes. :)