2012-04-18 33 views
12

Böyle bir yapıya sahip (Ben sadece bir dizi cant'kullanma nedense):sizeof üye hesaplama hatası

struct OperatorData 
    { 
    char m_record_0[RIX_OPERATOR_CONFIG_SIZE]; 
    char m_record_1[RIX_OPERATOR_CONFIG_SIZE]; 
    //.... 
    char m_record_9[RIX_OPERATOR_CONFIG_SIZE]; 
    }; 

Ve derleme sırasında alanların miktarını hesaplamak için çalışıyorum:

enum {fieldsAmount = sizeof(OperatorData)/sizeof(OperatorData::m_record_0)}; 

Ve derleyici raporları böyle bir mesaj:

Error: #245: a nonstatic member reference must be relative to a specific object 
    enum{fieldsAmount = sizeof(OperatorData)/sizeof(OperatorData::m_record_0)}; 
                   ^

Ben Keil uVision3 V3.60 kullanın. Yapının içinde veya dışında enum bildirimini nereye koyduğum önemli değil. Derleyici neden bu membranın boyutunu alamıyor?

+0

sizeof() bunları kullanmak hangi OperatorData bir örneğini olması gerekiyor (ayrıca doğru değil). – Matthias

+0

@Matthias: İşlenenin bir _lvalue_ olması gerekmez; türü, "sizeof" için uygun olduğu sürece izin verilir. –

+2

Ayrıca, http://stackoverflow.com/a/10207185/147763 –

cevap

12

Derleyici, değerlendirilmemiş ifadelerde Type::member kullanımına izin veren C++ 11'i desteklemiyor gibi görünüyor.

OperatorData* noImpl(); 

enum{fieldsAmount = sizeof(OperatorData)/sizeof(noImpl()->m_record_0)}; 
+0

+1. Güzel. Benimkinden daha iyi! – Nawaz

+1

Bu arada, 'OperatorData noImpl();' de iyidir. Sonra sizeof (noImpl(). M_record_0) 'yazdınız. – Nawaz

+0

"NoImpl" işlevi değil mi? –

0

m_record_0, OperatorData yapısının statik bir üyesi olmadığı içindir. Bunu yalnızca statik bir üye olduğunda yapabilirsiniz.

+0

adresinde açıklandığı gibi pragma tarafından kontrol edilen veri hizalamasını da düşünmelisiniz. Ancak derleme zamanında alan büyüklüğü değil midir? –

+0

Evet, sizeof doğru olan bir derleme zamanı operatörüdür. Sorun, m_record_0 yapınızın statik bir üyesi değilse, ne zaman olursa olsun, OperatörData :: m_record_0 tarafından üyeye başvuramazsınız. –

0

Yapınızın bir Nesnesi oluşturun ve üzerinde sizeof() numaralı işleç kullanın.

4

Bunun güvenli olduğunu düşünmüyorum; sizeof (OperatorData)'a dahil edilecek ancak üyelerin belirli bir boyutunda olmayan üyeler arasında veya sonrasında eklenen bir dolgu olabilir. Bir yakın sonucu elde etmek zaten mevcut RIX_OPERATOR_CONFIG_SIZE değerini kullanabilirsiniz Tabii

: o varsayarak

const size_t num_records = sizeof (OperatorData)/RIX_OPERATOR_CONFIG_SIZE; 

sadece char diziler için kullanılıyor ve herhangi dolgu cüceler söyledi. Bu da sadece bir yaklaşımdır olduğunu, yine,

const size_t num_records = sizeof (OperatorData)/
     (offsetof(OperatorData, m_record_1) - offsetof(OperatorData, m_record_0)); 

Not: Ayrıca offsetof() kullanabilirsiniz

, bu üyeler arasında en az dolgu dahil yararı vardır. Umarım, herhangi bir dolgu, üyelerin kendilerinden çok daha küçük olacaktır, böylece katkıları yuvarlanacaktır.

3

Statik olmayan bir üyeye :: işleci kullanılarak erişilemez.

C++ 11 olarak, (quick demo) bunu yapabilirsiniz: C++ 03

#include <utility> 

size = sizeof(OperatorData)/sizeof(std::declval<OperatorData>().m_record_0); 

Ve de, şunu yapın:

size = sizeof(OperatorData)/sizeof(((OperatorData*)(0))->m_record_0); 

ifade ((OperatorData*)(0)) tipi OperatorData* olduğunu

OperatorData* od = ((OperatorData*)(0)); 
size_t size = sizeof(od->m_record_0); 
:, bu yüzden bu eşdeğerdir boyutunu almak için ((OperatorData*)(0))->m_record_0 kullanmak 10

Ancak, tam olarak aynı değildir, yukarıdaki ifade çalıştırılacak, ancak sizeof() ifadesi yürütülmeyecektir.

5

Kullanım typedefs: gibi Doğru türde bir ifade üretmek gerekecek şey Ardından

typedef char RecordType[RIX_OPERATOR_CONFIG_SIZE]; 

struct OperatorData 
{ 
    RecordType m_record_0; 
    RecordType m_record_1; 
    //.... 
    RecordType m_record_9; 
}; 

:

enum {fieldsAmount = sizeof(OperatorData)/sizeof(RecordType)}; 
+0

+1: Dostum, benden daha hızlısın;) –