![](/img/trans.png)
[英]Why does the sizeof operator in C gives different output in case of NOT operation?
[英]Does C correctly handle sizeof(…) and sizeof … in this case?
在下面的代碼中,函數test
和test2
等效的嗎?
typedef int rofl;
void test(void) {
rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
}
void test2(void) {
rofl * rofl = malloc(sizeof *rofl); // Is the final rofl here the VARIABLE?
}
換一種說法:
rofl
中sizeof(rofl)
正確地挑rofl
類型 ,因為括號的? rofl
中sizeof *rofl
正確挑選rofl
變量 ,因為缺乏括號? 注意:這是一個看起來很愚蠢的例子,但在實踐中實際上你可以使用與變量名相同的類型名稱。 因此問題。
在這兩種情況下,最后一個rofl
是變量名。 變量名一出現就在范圍內; 對於當前范圍的其余部分,普通上下文(*)中的標識符始終表示變量名稱。
sizeof
運算符不會為名稱查找引入任何特殊情況。 實際上,沒有語言結構會使用標識符的隱藏含義。
實際上,不要對類型和變量名使用相同的標識符。
(*)標識符有三種特殊的上下文:標簽名稱,結構標簽和結構成員。 但在所有其他上下文中,所有標識符共享一個公共名稱空間:類型名稱與變量名稱與函數名稱等沒有明確的標識符名稱空格。
這是一個人為的例子:
typedef int A; // "A" declared as ordinary identifier, meaning a type name
struct A { A A; }; // "A" declared as struct tag and member name -- OK as these are three different name spaces. Member type is "int"
A main() // int main() - ordinary context
{
struct A A(); // "A" declared as ordinary identifier, meaning a function name; hides line 1's A
// A C; // Would be error: ordinary A is a function now, not a typedef for int
struct A B; // OK, struct tags have separate name space
A:+A().A; // OK, labels and struct members have separate name space, calls function
goto A; // OK, label name space
}
在這個宣言中
rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
變量rofl
的名稱隱藏了typedef名稱rofl
。 因此在sizeof運算符中使用了指針rofl
,該表達式的類型為int *
。
這同樣適用於此聲明
rofl * rofl = malloc(sizeof *rofl);
除了使用帶有解除引用指針rofl
的表達式,該指針具有typedef名稱rofl
的類型,即int
類型。
似乎由於這種C語法定義而產生混淆
sizeof unary-expression
sizeof ( type-name )
但是, unary-expression
可以是一個主表達式,它是括在括號中的表達式。
來自C標准(6.5.1主表達式)
primary-expression:
( expression )
//...
因此,例如,如果x
是變量的名稱,那么您可以編寫
sizeof x
要么
sizeof( x )
為清楚起見,您可以在sizeof運算符和主表達式之間插入空格
sizeof ( x )
operator primary expression
為了比較,考慮另一個一元運算符:一元加號。 你可以寫例如
+ x
要么
+ ( x )
現在只需將一元加號替換為另一個一元運算符sizeof
。
至於隱藏名稱,問題可以解析為結構,聯合和枚舉,因為它們的名稱包含標記的關鍵字。
例如
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( struct rofl));
}
在使用sizeof運算符的函數中,使用了type-name struct rofl
。
而在這個功能
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( rofl));
}
使用sizeof運算符時,使用帶有變量rofl
的主表達式,其類型為struct rofl *
。
沒有涉及“挑選”或“選擇”。 在兩種情況下rofl
在每個稱為sizeof
調用是變量,而不是類型,由於作用域規則。 變量在內部范圍聲明,因此會覆蓋類型名稱。 sizeof
運算符的參數括在括號中是無關緊要的。
祝你好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.