Cześć,
Jakiej wielkkości będzie enumy zdefiniowane następująco
enum A
{
a = 0
b= 7
};
enum B
{
c = 15
};
enub C
{
d = 2 << 60
};
I czy gcc i kompilator windowsa dadzą te same wyniki?
Cześć,
Jakiej wielkkości będzie enumy zdefiniowane następująco
enum A
{
a = 0
b= 7
};
enum B
{
c = 15
};
enub C
{
d = 2 << 60
};
I czy gcc i kompilator windowsa dadzą te same wyniki?
a tak trudno sprawdzić?
nie tak trudno, tylko że otrzymuję różne wartości i nie wiem dlaczego ?
Nie wiadomo jakiej wielkości są te enumy, ponieważ standard tego nie definiuje. Określa jedynie, że enum będzie reprezentowany przez typ zdolny do reprezentowania wszystkich wartości enuma. W każdym, bądź razie w powyższym przypadku obstawiałbym, że wszystkie enumy będą miały rozmiar 4 bajtów.
Dodam, że nie wiem jak się sprawa ma w C++0x z enum class.
Oba kompilatory dają bardzo podobny komunikat:
a.cpp:16:12: warning: left shift count >= width of type [enabled by default]
a.cpp(17) : warning C4293: '<<' : shift count negative or too big, undefined behavior
Hm,
rzeczywiście pod visual studio dostaję komunikat o za dużej liczbie, ale przecież Visual studio wspiera liczby 64 bitowe?
Po to właśnie jest enum class
. Możesz tam podać jaki typ ma być używany dla wartości i dzięki temu będziesz wiedział jaki rozmiar ma enum
.
#include <cstdint>
#include <climits>
#include <cassert>
enum class Test : std::uint64_t {
E1,
E2,
E3
};
int main() {
assert(sizeof(Test::E1) == sizeof(std::uint64_t));
return 0;
}
Ale z tego co wiem, enum class to ort! c++11, we wcześniejszych wersjach nie ma takiej możliwości.
Więc ogólnie nie mogę z góry założyć jaki dany enum ma rozmiar w starszych standardach?
Najwyraźniej nie zrozumiałeś w czym problem. Kompilator C++, gdy dostaje int, który jest przesuwany bitowo w prawo (operator <<), dokonuje tego przesunięcia w ramach danego typu! Nawet jeśli są to literały nie następuje awans do long long int na podstawie wartości, która nie mieści się w int. Z tego właśnie powodu ten kod na końcu pierwszej linijki drukuje zero, a kompilator zgłasza ostrzeżenie.
Mówić prosto "1<<x" zawsze będzie typu int be względu na wartość x (chyba, że x będzie typu long long).
Efekt jest taki, że do enum'a w swoim kodzie zawsze przypisujesz stałą (literał) typu "int", więc kompilator uznał, że taki typ wystarczy na twój enum.
W moim kodzie wymuszam typ literału na long long int dodają na końcu podwójne "L": "1ll<<35" nie powoduje pojawienie się warning. Wyniku ma typ long long int i taki typ potem wykorzystuje enum.
Czyli twój problem nie wynika z tego, że nie da się powiększyć rozmiaru enum'a, ale ze złej ewaluacji typu wartości.
Taki cóś jest bodajże w Winapi.
enum JakisTam
{
//..........
JT_FoceDword = 0xFFFFFFFF
};