sizeof(list) 如何區分list是變數還是類型?

#include &
typedef struct list
{
struct list * next;
int foo;
int bar;
}list;
int main()
{
list *list;
printf("%lu
",sizeof(list));
}


選取的是變數list,而非類型struct list.

typedef struct list
{
struct list * next;
int foo;
int bar;
}list;
int main()
{
list *list;
__builtin_printf("%lu
",sizeof(list));
}

clang++ -cc1 -ast-dump a.C

TranslationUnitDecl 0x263f770 &<&&> &

|-TypedefDecl 0x263fcb0 &<&&> & __int128_t "__int128"

|-TypedefDecl 0x263fd10 &<&&> & __uint128_t "unsigned __int128"

|-TypedefDecl 0x26400d0 &<&&> & __builtin_va_list "__va_list_tag [1]"

|-CXXRecordDecl 0x2640120 & line:1:16 struct list definition

| |-CXXRecordDecl 0x2640230 & col:16 struct list

| |-FieldDecl 0x2640370 & col:17 next "struct list *"

| |-FieldDecl 0x26403d0 & col:7 foo "int"

| `-FieldDecl 0x2640430 & col:7 bar "int"

|-TypedefDecl 0x268ab50 & col:2 list "struct list":"struct list"

|-FunctionDecl 0x268ac00 & line:7:5 main "int (void)"

| `-CompoundStmt 0x268b1b0 &

| |-DeclStmt 0x268adb8 &

| | `-VarDecl 0x268ad60 & col:9 list "list *"

| `-CallExpr 0x268b160 & "int"

| |-ImplicitCastExpr 0x268b148 & "int (*)(const char *, ...)" &

| | `-DeclRefExpr 0x268afe0 & "&" Function 0x268ae90 "__builtin_printf" "int (const char *, ...)"

| |-ImplicitCastExpr 0x268b198 & "const char *" &

| | `-StringLiteral 0x268b088 & "const char [5]" lvalue "%lu
"

| `-UnaryExprOrTypeTraitExpr 0x268b100 & "unsigned long" sizeof

| `-ParenExpr 0x268b0e0 & "list *" lvalue

| `-DeclRefExpr 0x268b0b8 & "list *" lvalue Var 0x268ad60 "list" "list *"

`-LinkageSpecDecl 0x268ae40 & col:3 C

`-FunctionDecl 0x268ae90 & col:3 __builtin_printf "int (const char *, ...)" extern

|-ParmVarDecl 0x268af30 &<&&> & "const char *"

`-FormatAttr 0x268af90 & printf 1 2 Implicit

看看黑體,我們就知道了。

而比較權威解釋的話,則是C++標準9.1.2

A class declaration introduces the class name into the scope where it is declared and hides any class, variable, function, or other declaration of that name in an enclosing scope (3.3). If a class name is declared in a scope where a variable, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier (3.4.4).

若你想要sizeof計算struct,那麼你需要使用sizeof(struct list).

另外,實際代碼寫出這樣的人一般都是拉出去槍斃五分鐘。


編譯的時候如果不知道那是個類型還是個變數,麻煩就大了。。。


sizeof是編譯期確定的,不是運行的時候,

編譯的時候自然是知道的,


如果一種語言允許你做奇怪的事情, 不代表它支持或你應該做奇怪的事情, 因為語言雖然有嚴格的規則決定確定的結果, 但你不一定和它想的一樣.

除去大小寫問題, 你的命名把 list 中的元素類型和 list 本身混淆了.


list變數shadow了list類型,所以是變數


推薦閱讀:

學c語言應該買什麼樣的電腦?
c語言編程軟體哪個好用?
x86上為什麼C語言調用一個函數要先把參數壓棧,之後才是返回地址?
C/C++中如何在main()函數之前執行一條語句?
哪些類型的應用必須用c語言寫?

TAG:編程 | C編程語言 |