簡體   English   中英

在這種情況下,C是否正確處理sizeof(...)和sizeof ...

[英]Does C correctly handle sizeof(…) and sizeof … in this case?

在下面的代碼中,函數testtest2等效的嗎?

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?
}

換一種說法:

  1. 是否roflsizeof(rofl)正確地挑rofl 類型 ,因為括號的?
  2. 是否roflsizeof *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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM