2012-06-26 43 views
1

我編譯的代碼,這使我的錯誤在以下功能:錯誤:從「字符*」到「無符號整數」鑄損失精度

inline char *align(char *var, DataType_e type) 
{ 
    return (DataTypeSize[type] == 0) ? var : 
     (char*) (((unsigned int)(var) + DataTypeSize[type]-1)/
       DataTypeSize[type] * DataTypeSize[type]); 
} 

下面的錯誤來本着「(無符號INT)(VAR)」:

error: cast from 'char*' to 'unsigned int' loses precision 

如果我改變‘無符號整型’到‘無符號長’,彙編作品,但我運行程序時,我沒有得到預期的結果。任何想法如何解決這個問題?

+3

預期結果是什麼?你能提供一些例子嗎? – glglgl

+1

您的預期成果是什麼?你能詳細說明一下嗎?出乎意料的是,你在一個使用'long'指針表示的環境中進行編譯。 –

+0

你確定這甚至是你想要做的嗎?根據你填寫'DataType_e'對象的方式,你找回的指針看起來很可能不會成爲有效的內存。 – Daniel

回答

0

當您要使用指針進行數學運算時,應該使用指針算術而不是將指針值轉換爲'int'或'long',計算並轉換回指針。這很容易導致錯誤的結果,因爲編譯器無法遵守計算的對齊規則。

我敢肯定,你的例子中函數的'意外'結果與演員完全沒有任何關係。您應該更多地解釋使用DataSize[type]值進行的計算以及您想要使用的值。

+0

除了你不能在指針上執行除法或乘法,並且'char *'沒有對齊規則。 –

+0

@MikeSeymour你通常不需要這樣做。你可以對'size_t'值執行除法和乘法操作,並將這些值加到或減去'錨'指針。 –

+0

但在這種情況下,我非常肯定你確實需要。除非您有辦法將地址四捨五入到給定的對齊方式,而無需直接操作其值,否則請更新答案以向我們展示如何。 –

5

在C中,如果您需要將指針轉換爲整數類型(但您應該首先避免使用),則應該使用[u]intptr_t

如果它們存在,這些類型保證不會丟失信息。

3

uintptr_t類型與指向POD的指針的大小相同。指向其他數據類型的指針,特別是指向成員函數的指針可以更大。

inline char *align(char *var, DataType_e type) 
{ 
    size_t alignSize = DataTypeSize[type]; 

    if (1 >= alignSize) { 
     return var; 
    } 

    uintptr_t varInt = reinterpret_cast<uintptr_t>(var); 
    varInt = alignSize * ((varInt + alignSize - 1)/alignSize); 

    return reinterpret_cast<char *>(varInt); 
} 
+1

'uintptr_t'對任何'void *'都有好處,因此適用於指向任何對象類型的指針,而不僅僅是POD。關於指向成員函數的約定 –

+0

@SteveJessop我認爲指向具有多重繼承的對象的指針也可能比'uintptr_t'更大,我從來沒有讀過這個標準,所以我可以完全脫離這個指針。 – IronMensan

+0

指針可以是任何* size *,但即使它佔據了比'void *'更多的存儲字節,任何指向對象類型的指針都可以被轉換爲void *'並返回並返回相同的值(5.2.9/13)。所以它不能「真正」變大即使某些特殊的實現使用額外的數據填充它。同樣,任何'void *'都可以轉換爲'uintptr_t'並返回。 –