Potrzebuje w moim programie tworzyć losowe liczby używając preprocesora.
Próbowałem czegoś takiego:
#define random ((int)__TIME__)
Lecz ku mojemu zdziwienie, przy każdej kompilacji to makro zwraca tą samą liczbę. Jest na to jakiś sposób ?
Potrzebuje w moim programie tworzyć losowe liczby używając preprocesora.
Próbowałem czegoś takiego:
#define random ((int)__TIME__)
Lecz ku mojemu zdziwienie, przy każdej kompilacji to makro zwraca tą samą liczbę. Jest na to jakiś sposób ?
Dodam, iż nie chodzi mi o to aby takie makro działało identycznie jak funkcja rand() (tj, że przy każdym wywołaniu daje inny wynik), lecz aby takie makro miało stałą wartość, lecz przy każdej kompilacji inną.
Przykład:
#define random ((int)__TIME__)
int main()
{
cout << random << endl;
cout << random << endl;
}
Taki program ma wyświetlić dwa razy tą samą liczbę, lecz przy każdej kompilacji ma to być inna liczba.
__TIME__
to ciąg znaków, zapewne kompilator co kompilację umieszcza go w tym samym miejscu w pamięci, zatem - jako, że próbujesz odczytać adres - otrzymujesz stałą liczbę.
Btw, *tę samą liczbę.
@Patryk27 zapewne masz rację w tej kwestii, a czy istnieje jakieś makro które zwraca wartość liczbową (inną, przy każdej kompilacji) ?
Afair jawnie takiego wbudowanego makra nie ma, natomiast jeżeliby się postarać, to można by pokombinować z constexpr
oraz makrem __TIME__
, lecz to byłoby naprawdę przesadzone.
Edit: podobno GCC wspiera jakiś swój system pluginów, z tym również można by spróbować...
Wpadłem na coś takiego:
#define gen_random(str) (unsigned long)((str[1] * str[4] + str[7]) * (str[0] + str[3] * str[6]))
#define random gen_random(__TIME__)
Lecz liczby przy następnych kompilacji są zbyt blisko siebie, ale wydaje mi się że to wystarczy, muszę tylko wymyślić coś co pozwoli mi jeszcze ustawić przedział od-do.
Można też użyć gcc my_file.c -Drandom=$RANDOM
(jeśli to powłoka zgodna z POSIX).
#define gen_random(str) (((((long)str[1]*str[4]+str[7])*(str[0]+(long)str[3]*str[6]))*214013L+2531011L)>>16)
#define random gen_random(__TIME__)
Będą trochę dalej
Dzięki, mogę założyć że takie makro 'random' jest 'constant-expression' tak ?
Tak, to makro jest wyrażeniem stałym, o wartości znanej już na poziomie kompilacji.
Hmm, więc dlaczego taki kod nie działa:
#define RANDOM(s) ((unsigned long)((s[0] * s[4] * s[6]) ^ (s[1] * s[3] * s[7])))
#define SEED RANDOM(__TIME__)
#define EC(c) EncryptChar<c, SEED>::v
template <char c, unsigned long key>
struct EncryptChar { enum { v = c ^ key }; };
static const long a = SEED;
static const char b = EC('a'); <-- tutaj dostaje błąd
Błąd brzmi: an array reference cannot appear in a constant-expression| template argument 2 is invalid|
Jak nie działa, jak działa (C++11
): http://ideone.com/0OyT9O
Dzięki po dodaniu: -std=c++11
jest okej ;)