Toon posts:

[Objective C] - Ik die iets stoms maar ik zie het niet.

Pagina: 1
Acties:

Onderwerpen


  • TumbleCow
  • Registratie: januari 2000
  • Laatst online: 08-07 11:41

TumbleCow

Waarschijnlijkheids elastiekje

Topicstarter
Ik heb de volgende situatie:

code:
1
2
3
4
5
6
7
8
9
- (void) processAllPastDataForStatistics  {
            float val = 23;// [[event batteryLevel] floatValue];
            [self updateStatistics:val];
            NSLog(@"value %f",val);
}

- (void) updateStatistics:(float) val  {
    NSLog(@"%f",val);
}


For some reason, geeft de NSLog in de 'updateStatistics' functie '0', terwijl de NSLog in de processAllPastDataForStatistics() wel netjes '23' geeft.
Dit is zo'n enorm simpel probleem dat ik wel iets heel stoms over het hoofd moet zien, maar het ontgaat me. Enig idee?

  • TumbleCow
  • Registratie: januari 2000
  • Laatst online: 08-07 11:41

TumbleCow

Waarschijnlijkheids elastiekje

Topicstarter
En.. Naar er inmiddels een uur naar gestaard te hebben los ik het zelf 'op', 2 minuten nadat ik het dan toch maar op GoT ga vragen.

Vreemd genoeg, werkt de volgende code wel:
code:
1
2
3
4
5
6
7
8
9
- (void) updateStatistics:(float) val  {
    NSLog(@"%f",val);
}

- (void) processAllPastDataForStatistics  {
            float val = 23;// [[event batteryLevel] floatValue];
            [self updateStatistics:val];
            NSLog(@"value %f",val);
}

Iow: Alleen het omwisselen van de functies in de source-file lost het probleem op.

Natuurlijk klopt het dat ik de 'updateStatistics' functie bovenaan moet zetten: Ik declareer de functie nergens, en er is een risico dat compiler de functie niet kan vinden.
Het bijzondere is nu dat de compiler de functie prima vindt. In een debugger, kan ik zelfs netjes door de functie heen lopen. Het enige dat mis gaat, is dat de 'val' een dangling pointer wordt. Weird.

  • MacWolf
  • Registratie: januari 2004
  • Laatst online: 11-07 17:51
Probeer eens 23.0f te gebruiken als waarde, ipv 23.

Edit: ik zie dat je op hetzelfde moment gepost hebt als ik, nou ja net iets eerder :). Zijn beide functies in de header gedefinieerd?

Edit 2: als je niet duidelijk een getal als float definieert d.m.v. de .0f notatie, dan is de kans groot dat de compiler er een integer van maakt. Als je daarna het getal als parameter naar een andere functie doorgeeft, krijgt deze dus een integer en kan het niet meer terug converteren naar de originele waarde. Voor de veiligheid, zorg er altijd voor dat als je een float definieert, dat deze de .0f notatie gebruikt.

[Voor 110% gewijzigd door MacWolf op 05-11-2010 18:49]

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.


  • TumbleCow
  • Registratie: januari 2000
  • Laatst online: 08-07 11:41

TumbleCow

Waarschijnlijkheids elastiekje

Topicstarter
Bedankt voor het meedenken!
MacWolf schreef op vrijdag 05 november 2010 @ 18:46:
Edit: ik zie dat je op hetzelfde moment gepost hebt als ik, nou ja net iets eerder :). Zijn beide functies in de header gedefinieerd?
Nee, dat zijn ze niet, en dat is dan ook het probleem. ;)
Edit 2: als je niet duidelijk een getal als float definieert d.m.v. de .0f notatie, dan is de kans groot dat de compiler er een integer van maakt. Als je daarna het getal als parameter naar een andere functie doorgeeft, krijgt deze dus een integer en kan het niet meer terug converteren naar de originele waarde. Voor de veiligheid, zorg er altijd voor dat als je een float definieert, dat deze de .0f notatie gebruikt.
Ik snap dat het hier nu anders lijkt, maar ik ben een redelijk ervaren programmeur, en ben dus wel bekend met de problemen bij conversie tussen float en int. Dit is iets meer dan een afrondingsfoutje. :)

Het lijkt er op dat de compiler (LLVM 1.5) wel de functie kan resolven, ookal is hij later gedefinieerd als de call. Fancy.
However, het resolven van de parameters van de functie gaat mis, en de parameter wordt een dangling pointer. Hoewel het aanroepen van een niet gedefinieerde functie een programmeerfout (van mij :P) is, beschouw ik dit gedrag als een fout in de compiler.

  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
DIt gedrag is ook standaard in C. Als een functie op het moment van aanroepen niet gedeclareerd is (of wel gedeclareerd, maar de types van de parameters niet), dan worden de parameters naar een defaulttype geconverteerd. Alles wat kleiner is dan een int wordt als int gepasst; floats worden als double gepasst. Dit gebeurt bijvoorbeeld ook wanneer je extra argumenten aan een functie met variabele argumenten (zoals printf() passt).

Op de x86 architectuur waar je waarschijnlijk op werkt wil het toeval dat floats normaalgesproken als 32-bit argument gepasst worden en doubles als 64-bit argument. Dat betekent dat je in de eerste functie een 8 bytes waarde op de stack plaatst, maar de tweede functie bekijkt alleen maar de eerste 4 bytes omdat een float verwacht werd. In een little-endian representatie van (double)23.0 zijn de eerste 4 bytes toevallig nul. Als je die als float interpreteert krijg je er dan nul uit.

Dat het verder niets met de OO-extensies van Objective C te maken heeft, blijkt uit het feit dat dit C programma precies hetzelfde probleem kent:
C:
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main(int argc, char **argv)
{
        float f = 23.0;
        print(f);  /* float wordt hier naar double geconverteerd */
}

void print(float f)
{
        printf("%f\n", f);  /* print 0.00 */
}

Ik weet trouwens niet welke compiler jij gebruikt, maar de mijne geeft een duidelijke waarschuwing dat de definitie op regel 9 niet compatibel is met degene waar de compiler op regel 6 vanuit ging:
test.c:9: warning: conflicting types for ‘print’
test.c:6: note: previous implicit declaration of ‘print’ was here
Overigens kun je er niet vanuit gaan dat je zo'n waarschuwing krijgt. Als de functies apart gecompileerd worden kan de compiler ook niet zien dat ze incompatibel zijn.

  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
wHiTeRaZoR schreef op vrijdag 05 november 2010 @ 19:04:
Het lijkt er op dat de compiler (LLVM 1.5) wel de functie kan resolven, ookal is hij later gedefinieerd als de call. Fancy.
Dit is standaard gedrag in C sinds 1972 ofzo. :P
However, het resolven van de parameters van de functie gaat mis, en de parameter wordt een dangling pointer.
Dit heeft niets met dangling pointers te maken.
Hoewel het aanroepen van een niet gedefinieerde functie een programmeerfout (van mij :P) is, beschouw ik dit gedrag als een fout in de compiler.
De compiler gedraagt zich 100% correct in dit geval. Het enige gebrek is dat LLVM je blijkbaar niet waarschuwt, maar dat is meer een optionele feature.

  • TumbleCow
  • Registratie: januari 2000
  • Laatst online: 08-07 11:41

TumbleCow

Waarschijnlijkheids elastiekje

Topicstarter
Grappig, bedankt voor de verduidelijking. Ik ben er zelf nooit eerder tegenaan gelopen, en het is duidelijk dat ik na een jaar op een java-project een verwend nest geworden ben. ;)
Soultaker schreef op vrijdag 05 november 2010 @ 19:34:
Dit heeft niets met dangling pointers te maken.
Nee, dat begrijp ik nu. Het gedrag leek hier op, omdat ik in de 'echte' implementatie allerlei seemingly ongerelateerde nummers in mijn functie kreeg, maar mijn interpretatie van wat er mis ging was way off.

Geen compiler bug dus, maar gewoon een tijs-bug. - Type-safety is for wussies anyway. :P

[Voor 7% gewijzigd door TumbleCow op 05-11-2010 23:55]


  • Soultaker
  • Registratie: september 2000
  • Laatst online: 22-07 23:43
wHiTeRaZoR schreef op vrijdag 05 november 2010 @ 23:52:
Grappig, bedankt voor de verduidelijking. Ik ben er zelf nooit eerder tegenaan gelopen, en het is duidelijk dat ik na een jaar op een java-project een verwend nest geworden ben. ;)
In C is het tegenwoordig ook gebruikelijk om gewoon de juiste functiedeclaraties eerst via een header file te includen, juist om dit soort fouten te voorkomen. Impliciete functiedeclaratie is een nogal archaïsche feature, die bijvoorbeeld in C++ helemaal niet meer ondersteund wordt, en komt zo zelden voor in goede code dat je je niet hoeft te schamen dat je er niet bekend mee was. (Maar het is nog steeds nuttig om te weten hoe argumenten gepasst worden, omdat dat bij variable argumenten van een functie op dezelfde manier gebeurt.)
Het gedrag leek hier op, omdat ik in de 'echte' implementatie allerlei seemingly ongerelateerde nummers in mijn functie kreeg, maar mijn interpretatie van wat er mis ging was way off.
Mja, ik vond het enigzins zorgwekkend dat je over dangling pointers begon bij een stukje code waar lettelijk geen enkele pointer in voorkomt. :P

  • TumbleCow
  • Registratie: januari 2000
  • Laatst online: 08-07 11:41

TumbleCow

Waarschijnlijkheids elastiekje

Topicstarter
Soultaker schreef op zaterdag 06 november 2010 @ 00:06:
(Maar het is nog steeds nuttig om te weten hoe argumenten gepasst worden, omdat dat bij variable argumenten van een functie op dezelfde manier gebeurt.)
Absoluut! - Ik snap liever wat er gebeurt in plaats van dat ik mijn handen in de lucht gooi en roep: 'Wat heeft C nu weer gedaan!'.
Dus, daarvoor mijn dank. :)
Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee