Po letech na Unixu a Windows to chci zase zkusit na mikrokontrolérech. V AVR studiu s instalovaným pluginem WinAVR jsem v C zkusil následující:
#include <avr\io.h>
#include <string.h>
int main(int argc, char* arvg[])
{
char* ahoj = "ahoj";
char* ptr;
ahoj[2] = PINB;
ptr = strchr(ahoj, 'h');
PORTC = *++ptr;
}
problém je, že prográmek pracuje jinak , když není nastavena optimalizace (-O0) a jinak když je nějaká nastavena - třeba -Os.
Je-li optimalizace nastavena, kompilátor umístí řetězec ahoj do kódového segmentu a jelikož tam nelze zapisovat, tak vynechá celé řádky se čtením z portu B a s funkcí strchr() . Přitom není vydáno žádné varování, i když gcc má zapnuto -Wall .
Jak donutit kompilátor dávat řetězec do SRAM - přišel jsem na jediné:
volatile char* ahoj = "ahoj";
což se mi ovšem nepozdává, vzhledem k tomu, že volatile má primárně jiný význam. Existuje nějaký konformnější způsob?
Umístění řetězce do SRAM
Moderátor: Moderátoři
Tak jsem se informoval, volatile znamená zákaz optimalizací při práci s danou proměnou, což celou věc vysvětluje. Pokud to uděláš jak jsi napsal, bez volatile, tzn. při deklaraci tringu uložíš rovnou hodnotu a už s ní v celém programu nehýbeš, tak ji kompilér v rámci zrychlení a ušetření pamětí považuje za konstant char, ikdyž mu to nespecifikuješ, ale záměnou se nic nestane, pokud ale hodnotu alespoň jednou během programu změníš, už by záměna neplatila, použitím volatile se možností záměny ani nebude zabývat.
Jasně, že by to šlo, ale elegance se vytratí. Všechny varianty od AB1 fungují, to je OK, jenom by gcc mohl dát nějaké varování, že aplikace chce zapisovat někam, kde to nejde, když už s proměnnými cvičí po segmentech,Zmije píše:Moc se v tajích optimalizace nevyznám, ale nepomohlo by nadeklarovat nejdříve prázdné pole(třeba samé nuly) pro řetězec a naplnit ho až během programu? Takhle si to kompilér vyhodnotí jako konstantní řetězec.