[C] Geheugengebruik sprintf

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Ik ben bezig C op een embedded device (Microchip PIC33). Er valt me op dat het geheugen gebruik ineens met 128 bytes toeneemt als ik mijn code aanpas, en ik snap niet waarom. Misschien dat iemand met meer embedded ervaring hier een lichtje op kan laten schijnen.

C:
1
2
3
4
5
6
// oude situatie
sprintf(buff,  "S%04d", 100);

// nieuwe situatie, er is ineens 128 bytes meer statisch geheugen gealloceerd
char *t = "S%04d";
sprintf(buff, t, 100);


Ik weet dat sprintf wordt afgeraden voor embedded toepassingen, ben ook al bezig om dat eruit te slopen. Maar toch vraag ik me af waarom dit uitmaakt.

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


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 20-09 19:58

Sebazzz

3dp

Niet als je hem const maakt.

edit: Uitleg: const waardes zijn bekend wanneer je bestand gecompileerd wordt en kunnen in de datatabel van je applicatie worden opgeslagen. Dat kan later direct worden opgevraagd. Wat je nu doet is het kopieren vanuit de tabel omdat je een aanpasbare char* t hebt in plaats van een constante. Overigens moet het char[] *t zijn? :?

[ Voor 85% gewijzigd door Sebazzz op 30-06-2010 17:30 ]

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


Acties:
  • 0 Henk 'm!

Verwijderd

Ik ben niet ervaren in C, maar je declareert in je nieuwe situatie een char pointer naar een stuk geheugen waar je "S%04d" in opslaat. Dan zal dit waarschijnlijk die 128 bytes verklaren.

Als je namelijk direct een variable sprintf't hoeft er niks in het geheugen opgeslagen te worden

ik kan me vergissen

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Sebazzz schreef op woensdag 30 juni 2010 @ 17:28:
Overigens moet het char[] *t zijn? :?
Dat zou een array van strings zijn. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op woensdag 30 juni 2010 @ 17:32:
Ik ben niet ervaren in C, maar je declareert in je nieuwe situatie een char pointer naar een stuk geheugen waar je "S%04d" in opslaat. Dan zal dit waarschijnlijk die 128 bytes verklaren.

Als je namelijk direct een variable sprintf't hoeft er niks in het geheugen opgeslagen te worden

ik kan me vergissen
Zelfs als ik die regel waar ik de variabele in zet laat staan in mijn code dan nog gebruikt die tweede situatie meer geheugen.

Ik snap het verschil niet, in beide gevallen geef ik een pointer mee aan die functie. In het ene geval staat het in het programmageheugen. Die pointer t wijst ook naar het programmageheugen, die string blijft een constante.

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


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 20-09 19:58

Sebazzz

3dp

NMe schreef op woensdag 30 juni 2010 @ 17:53:
[...]

Dat zou een array van strings zijn. ;)
Uhm, een array van characters toch? En dus een C-style string.
http://www.cprogramming.com/tutorial/lesson9.html
Ik snap het verschil niet, in beide gevallen geef ik een pointer mee aan die functie. In het ene geval staat het in het programmageheugen. Die pointer t wijst ook naar het programmageheugen, die string blijft een constante.
Je declareert het niet als constante en de compiler optimaliseert het dus niet. Je *t kan je op ieder gewenst moment aanpassen.

[ Voor 40% gewijzigd door Sebazzz op 30-06-2010 18:13 ]

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


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je bedoelt char t[], niet char[]* t. Die laatste is idd een array van pointes (al klopt de syntax niet, het zou dan char* t[] moeten zijn, maar soit).

Verder lijkt me dat Sebazzz idd gelijk heeft, al klopt dat niet helemaal met wat C hoort te doen. Iets als char * t = "hoi" is eigenlijk sowieso fout. Het betekent niet dat je t dan aan mag passen, want die wijst nog altijd naar een const char *, alleen wordt dat (een const string literal aan een non-const char pointer assignen) expliciet toegestaan in de standaard. Als je 'm aan wilt kunnen passen dan moet je [] gebruiken, niet *.

[ Voor 134% gewijzigd door .oisyn op 30-06-2010 18:24 ]

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!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Meen dat je expliciet ‘ROM’ moest toevoegen voor strings:
C:
1
const rom char *t = "S%04d";

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-09 18:51
Ik denk dat het gewoon een rariteit in de compiler is. Kleine verschillen in source code kunnen ongewenste veranderingen in de gegenereerde objectcode tot gevolg hebben. Misschien dat in het tweede geval een aantal statische objecten in een andere volgorde wordt geplaatst, wat misschien door alignment een paar bytes meer kost, waardoor de data section weer net te groot wordt, en met 128 bytes uitgebreid wordt. Maar zonder de gegenereerde objectcode te zien is er weinig zinnigs over te zeggen.

In ieder geval heb ik wel vreemdere dingen gezien, en ik zou me er persoonlijk niet zo druk om maken.

edit:
Maar misschien hebben Sebazz en Icelus gelijk en implementeert je compiler de C standaard niet goed. Dan zou 'ie dus de string in writable memory alloceren omdat je 'm aan een char* toekent. Maar dan nog lijkt me dat het verschil in geheugengebruik 'm alleen zit in sections die anders gepad worden. Nog steeds niet echt iets om je zorgen om te maken.

[ Voor 23% gewijzigd door Soultaker op 30-06-2010 18:37 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

.oisyn schreef op woensdag 30 juni 2010 @ 18:19:
Als je 'm aan wilt kunnen passen dan moet je [] gebruiken, niet *.
offtopic:
:o En ik maar denken dat char *t en char t[] synoniem waren. Ik moet echt mijn C-kennis eens afstoffen. :X

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Alleen als functieparameters. char *t is een pointer, char t[] is een array. Die laatste mag dan ook alleen als je 'm direct initaliseert, want de grootte van de array moet af te leiden zijn uit de initialisatie. Of hij moet extern zijn. In het geval van char t[] = "hallo" is t dus gewoon een char[6].

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!

  • Exirion
  • Registratie: Februari 2000
  • Laatst online: 12:26

Exirion

Gadgetfetisjist

.oisyn schreef op woensdag 30 juni 2010 @ 21:42:
Alleen als functieparameters. char *t is een pointer, char t[] is een array. Die laatste mag dan ook alleen als je 'm direct initaliseert, want de grootte van de array moet af te leiden zijn uit de initialisatie. Of hij moet extern zijn. In het geval van char t[] = "hallo" is t dus gewoon een char\[6].
Een ander onderscheid is dat de char t[] array in z'n geheel op de stack van de functie wordt gezet. Je kunt dit mooi zien als je een char t[] aanmaakt in een recursieve functie: elke keer dat de functie zichzelf aanroept zie je de pointerwaarde van t omlaag zakken. Daarentegen zal een char *t bij elke recursieve aanroep nogsteeds naar hetzelfde stukje geheugen wijzen.

"Logica brengt je van A naar B, verbeelding brengt je overal." - Albert Einstein


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Soultaker schreef op woensdag 30 juni 2010 @ 18:34:
In ieder geval heb ik wel vreemdere dingen gezien, en ik zou me er persoonlijk niet zo druk om maken.
Ik maak me er druk om omdat ik nu een heap van 4K groot heb (hoe groter hoe beter, want ik heb redelijk wat dynamisch geheugen nodig), en mijn stack minimaal 512 bytes moet blijven. Door dit geintje is mijn stack ineens 430 bytes groot geworden. Maar goed, ik heb nog links en rechts wat optimalisaties te doen.

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


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom reageer je niet op Sebazzz' suggestie?

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
Omdat het aanpasbaar moet zijn. Of tenminste, omdat er gekozen moet kunnen worden uit enkele opties. Ik zal eens kijken wat het const maken doet, maar als ik het me goed herinner hielp dat niet.

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


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dus de formatstring die je aan sprintf() geeft moet aanpasbaar zijn?

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!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-09 18:51
Grijze Vos schreef op donderdag 01 juli 2010 @ 01:06:
Ik maak me er druk om omdat ik nu een heap van 4K groot heb (hoe groter hoe beter, want ik heb redelijk wat dynamisch geheugen nodig), en mijn stack minimaal 512 bytes moet blijven.
Ok, maar dan moet je de gegenereerde object files eens in detail bekijken zodat je kunt zien waar de ruimte heen gaat (nu, en voor de wijziging). Nu zie je alleen het totaal en daaruit kun je de oorzaak niet afleiden.

Ik vermoed dat er nu een extra sectie gegenereert wordt ofzoiets. Op zichzelf lijkt me dat nog steeds geen ramp, behalve als je die ~100 bytes echt nodig hebt. Dan kun je misschien de compileropties nog tweaken om bijvoorbeeld de alignment van secties te tweaken, of alle data secties te mergen (een aparte read-only sectie is voor embedded development niet altijd nodig).

Ik neem aan dat je programma sowieso vrij kort is, anders zal je zo een meervoud van 100 bytes kwijt zijn puur aan code.

[ Voor 51% gewijzigd door Soultaker op 01-07-2010 02:24 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
.oisyn schreef op donderdag 01 juli 2010 @ 01:53:
Dus de formatstring die je aan sprintf() geeft moet aanpasbaar zijn?
Inderdaad.
Soultaker schreef op donderdag 01 juli 2010 @ 02:20:
[...]

Ok, maar dan moet je de gegenereerde object files eens in detail bekijken zodat je kunt zien waar de ruimte heen gaat (nu, en voor de wijziging). Nu zie je alleen het totaal en daaruit kun je de oorzaak niet afleiden.

Ik vermoed dat er nu een extra sectie gegenereert wordt ofzoiets. Op zichzelf lijkt me dat nog steeds geen ramp, behalve als je die ~100 bytes echt nodig hebt. Dan kun je misschien de compileropties nog tweaken om bijvoorbeeld de alignment van secties te tweaken, of alle data secties te mergen (een aparte read-only sectie is voor embedded development niet altijd nodig).
Er wordt inderdaad een extra sectie gegenereerd, wat ik me afvraag is waarom. Ik weet niet of dat kan met dit apparaat. Ben niet zo bekend met de hardware, en een deel van de code is precompiled meegeleverd door een andere partij, daar heb ik ook niet echt invloed op.
Ik neem aan dat je programma sowieso vrij kort is, anders zal je zo een meervoud van 100 bytes kwijt zijn puur aan code.
Mwoah, het gaat om een interpreter zodat er software geprogrammeerd kan worden met een simpele DSL, omdat met handmatige C code het programmageheugen snel vol zat. Nu blijkt het datageheugen ook een probleem te zijn op sommige punten. Qua programmageheugen zit ik nog prima (75% in gebruik van de 128K), maar het datageheugen is problematisch: 11.5K in gebruik door het gedeelte dat de third party heeft gebouwd, +-512 bytes voor de stack, en 4K voor de heap, waarbij ik zoveel mogelijk wil opslokken als mogelijk is voor de heap.

[ Voor 81% gewijzigd door Grijze Vos op 01-07-2010 10:10 ]

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


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-09 18:51
Ik neem aan dat je 512 bytes stack bedoelt (en niet 512 K) anders ben je natuurlijk op de compleet verkeerde post aan het bezuinigen? Maar erm, string data kan dus niet in de code secties gealloceerd worden (die waarschijnlijk read-only zijn)?

Als Sebazzz en Icelus suggesties niet helpen helpt dit misschien:
C:
1
char format[] = "S%04d";

Of desnoods zo (onder de aanname van een 32-bit big-endian architectuur):
C:
1
2
3
4
int temp[2];
temp[0] = 0x53253034;
temp[1] = 0x64000000;
char *format = (char*)temp;

Als dat niet in de code sectie terecht komt weet ik 't ook niet meer.

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Nope, werkt ook niet. Ik hou het maar op een compiler optimalisatie die hier niet uitgevoerd kan worden .

[ Voor 66% gewijzigd door Grijze Vos op 01-07-2010 10:23 ]

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


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Soultaker schreef op woensdag 30 juni 2010 @ 18:34:
edit:
Maar misschien hebben Sebazz en Icelus gelijk en implementeert je compiler de C standaard niet goed. Dan zou 'ie dus de string in writable memory alloceren omdat je 'm aan een char* toekent.
Hoezo niet goed? De C standaard staat een heleboel toe. Functies in writeable memory zetten? Zelfs dat is volkomen legitiem. Immutable strings in ROM zetten is een niet-verplichte optimalisatie.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wat raar is is dat er een verschil zit tussen const char * str = "hoi" en char * str = "hoi". In beide gevallen mag je 'm niet aanpassen, ookal is die tweede non-const.

[ Voor 3% gewijzigd door .oisyn op 01-07-2010 12:45 ]

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!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
.oisyn schreef op donderdag 01 juli 2010 @ 12:45:
Wat raar is is dat er een verschil zit tussen const char * str = "hoi" en char * str = "hoi". In beide gevallen mag je 'm niet aanpassen, ookal is die tweede non-const.
Weet niet welke compiler gebruikt wordt maar Microchips compiler zet strings standaard in ROM. Vandaar dat beiden niet zijn aan te passen. (Heb voornamelijk met de 8-bit PIC18 gewerkt. Misschien dat de 32-bit PIC3x anders is).

[ Voor 9% gewijzigd door Icelus op 01-07-2010 13:09 ]

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het punt ontgaat je volgens mij. Wat ik zeg is dat volgens de C standaard je beide strings niet aan mag passen. Dat wel doen resulteert in undefined behaviour.

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!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11:51
Kan het het verschil zijn tussen wel en niet een static store (die misschien wel default een grootte heeft van 128bytes ) ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-09 18:51
MSalters schreef op donderdag 01 juli 2010 @ 10:23:
Hoezo niet goed? De C standaard staat een heleboel toe. Functies in writeable memory zetten? Zelfs dat is volkomen legitiem. Immutable strings in ROM zetten is een niet-verplichte optimalisatie.
Ok, daar heb je technisch gelijk in, ik neem het terug. :)

Het punt was dat de compiler string literals die aan een char* worden toegekend op een andere manier alloceert dan wanneer ze aan een const char* worden toegekend, waarvoor in de C standaard geen enkele aanleiding te vinden is. Dat is ook het punt dat .oisyn (herhaaldelijk) maakt. Maar je hebt gelijk dat de C standaard dit gedrag niet verbiedt.

Het is in dit geval wel vervelend omdat het blijkbaar tot meer overhead leidt terwijl daar (voor standaard C programma's) geen noodzaak toe was.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Had ik al gezegd dat je een string literal geassigned aan een char* niet aan mocht passen?

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!

  • Emmeau
  • Registratie: Mei 2003
  • Niet online

Emmeau

All your UNIX are belong to us

Kan die C compiler niet gewoon asm source uitspugen?
Dan vergelijk je de asm sources en weet je waardoor het precies komt.

En anders compileer je die 2 proggies en gooi je ze door een disassembler /debugger , kom je er ook wel.

If you choose to criticise you choose your enemies


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11:51
...11.5K in gebruik door het gedeelte dat de third party heeft gebouwd...
Hum, van de 16k neemt dit stuk 11.5K in? Valt daar niet wat te winnen?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
Welke compiler gebruik je? De Microchip MPLAB C compiler heeft iig aardig wat eigenaardigheden. De DSC pics zijn voor mij even geleden maar ik meen dat rom pointers een ander type zijn als data pointers en dat deze ook anders benaderd worden en niet aan elkaar assignable zijn (of was dat alleen bij de 18f PICs?). Een string die in een gewone char * moet kan dan dus niet in program memory staan omdat je compiler dan niet zou weten welke instructies die moet gebruiken om de data te laden. Ook hebben de string functies overloads voor data en rom strings, het kan maar zo zijn dat er een overload die eerst niet gebruikt werdt nu wel wordt gebruikt met extra geheugen gebruik tot gevolg (maar dat zou alleen voor je program memory moeten gelden).

Het is bij alle embedded compilers (en zeker die van chip fabrikanten) het waard om de manual is goed door te nemen aangezien deze compilers vaak ook op enkele (of veel) vlakken van de C standaard afwijken. Waarschijnlijk staat er wel iets in over met welke modifier je kan bepalen waar in welk geheugen en/of welke sectie je string komt te staan. Als je dan toch aan het lezen bent bekijk dan ook je linker manual en de inhoud van je linker script voor het zelfde geld maakt ie daar nu gewoon een sectie met wat extra ruimte die die eerst weg optimaliseerde.

[ Voor 8% gewijzigd door jmzeeman op 01-07-2010 22:55 ]


Acties:
  • 0 Henk 'm!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 20-09 18:03
Het grote verschil tussen de oude en nieuwe code, is dat de compiler er nu veel minder mee kan... "t" wijst naar een format string, maar t kan veranderen en naar een andere format string gaan wijzen...

Daarentegen, als de formatstring direct aan sprintf wordt meegegeven, kan de compiler daar veel meer mee... Zo geeft GCC bijvoorbeeld al waarschuwingen als het aantal of type argumenten niet overeenkomen. Maar in het geval van de oude situatie is ook het argument constant en is het eindresultaat van de formatstring tijdens het compileren al bekend. Ik sta er niet van te kijken als de gegenereerde code in feite een strcpy doet van "S0100". Het zou dan in elk geval niet de enige/eerste compiler zijn die dat optimaliseert... Weer andere (embedded) compiler "zien" dat je alleen de code voor het evalueren van %04d nodig hebt, dat scheelt dan dus ook weer de nodige code.

offtopic: Nooit gedacht dat ik nog iets toe te voegen had, waarbij .oisyn, MSalters en NMe me niet al voor waren...

[ Voor 7% gewijzigd door Elijan9 op 03-07-2010 12:17 . Reden: typo ]

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Elijan9 schreef op zaterdag 03 juli 2010 @ 12:03:
offtopic: Nooit gedacht dat ik nog iets toe te voegen had, waarbij .oisyn, MSalters en NMe me niet al voor waren...
Heb je de topic dan überhaupt wel doorgelezen? Want:
Het grote verschil tussen de oude en nieuwe code, is dat de compiler er nu veel minder mee kan... "t" wijst naar een format string, maar t kan veranderen en naar een andere format string gaan wijzen...
Volgens mij heb ik nu al 4x gezegd dat je een string literal sowieso nooit mag aanpassen, ook al assign je 'm aan een non-const pointer. Dit resulteert dus in undefined behaviour:
C:
1
2
3
4
5
void foo()
{
    char * t = "Hallo";
    t[0] = 'P';
}

En 't' zelf mag je natuurlijk sowieso aanpassen, ookal is het een const char *. Het is namelijk geen char * const of const char * const.
Dit is natuurlijk wel correct
C:
1
2
3
4
5
void foo() 
{ 
    char t[] = "Hallo"; 
    t[0] = 'P'; 
}

Maar dan kun je 't' weer niet naar een andere buffer laten wijzen.

[ Voor 40% gewijzigd door .oisyn op 04-07-2010 00:39 ]

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!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 20-09 18:03
.oisyn schreef op zondag 04 juli 2010 @ 00:38:
Heb je de topic dan überhaupt wel doorgelezen? Want:

[...]

Volgens mij heb ik nu al 4x gezegd dat je een string literal sowieso nooit mag aanpassen, ook al assign je 'm aan een non-const pointer.
Volgens mij mis jij de strekking van mijn verhaal. De string literal mag je niet aanpassen, maar de t mag je wel naar een andere string literal laten wijzen. Daarom weet de compiler niet stellig op het moment van de sprintf dat de formatstring hier altijd "S%04d" zal zijn en dus kan de compiler hier onmogelijk een strcpy van maken van "S0100".

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Elijan9 schreef op zondag 04 juli 2010 @ 14:58:
[...]

Volgens mij mis jij de strekking van mijn verhaal. De string literal mag je niet aanpassen, maar de t mag je wel naar een andere string literal laten wijzen. Daarom weet de compiler niet stellig op het moment van de sprintf dat de formatstring hier altijd "S%04d" zal zijn en dus kan de compiler hier onmogelijk een strcpy van maken van "S0100".
Die optimalisatie gebeurd iig niet. De 100 in mijn voorbeeld is een simplificatie. In de echte code is dit een variabele.
jmzeeman schreef op donderdag 01 juli 2010 @ 22:43:
Welke compiler gebruik je? De Microchip MPLAB C compiler heeft iig aardig wat eigenaardigheden. De DSC pics zijn voor mij even geleden maar ik meen dat rom pointers een ander type zijn als data pointers en dat deze ook anders benaderd worden en niet aan elkaar assignable zijn (of was dat alleen bij de 18f PICs?). Een string die in een gewone char * moet kan dan dus niet in program memory staan omdat je compiler dan niet zou weten welke instructies die moet gebruiken om de data te laden. Ook hebben de string functies overloads voor data en rom strings, het kan maar zo zijn dat er een overload die eerst niet gebruikt werdt nu wel wordt gebruikt met extra geheugen gebruik tot gevolg (maar dat zou alleen voor je program memory moeten gelden).
Ik denk dat dit het is. En dat hun implementatie(s) van sprintf een buffer in het statisch geheugen gebruiken. En om de twee implementaties ieder hun eigen buffer ofzo.

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

Pagina: 1