8

我不明白为什么这段代码在 C 中打印 1,但在 C++ 中打印其他数字?

#include <stdio.h>
static char T = 'a';
int main(int argc, char** argv) {
    struct T { char X[2]; };
    printf("size of T is %zu\n", sizeof(T));
}

为什么这段代码在 C 和 C++ 中都打印 1?

#include <stdio.h>
int main(int argc, char** argv) {
    static char T = 'a';
    struct T { char X[2]; };
    printf("size of T is %zu\n", sizeof(T));
}

有人可以解释一下吗?

4

3 回答 3

21

因为在C结构中被调用struct T而不仅仅是T. 在 C++ 中, 的局部定义struct T将隐藏全局变量T

#include <stdio.h>
static char T = 'a'; // (1)
int main(int argc, char** argv) {
    // `struct T` shadows outer `T` in C++
    struct T { char X[2]; }; // (2)

    // C: sizeof char (1); C++: sizeof struct T (2)
    printf("size of T is %u\n", sizeof(T));

    // C/C++: sizeof struct T (2)
    printf("size of struct T is %u\n", sizeof(struct T));
}

另一方面,当两个声明在相同的命名上下文中时,标识符的歧义T将导致相同的结果,因为 C++ 期望您指定您确实要使用 struct 而不是char T

#include <stdio.h>
int main(int argc, char** argv) {
    static char T = 'a';
    struct T { char X[2]; };
    printf("size of T is %u\n", sizeof(T)); // sizeof (char)
    printf("size of struct T is %u\n", sizeof(struct T));// sizeof struct T
}

这导致 C 和 C++ 的大小相同。

如何避免这种错误

通常编译器确实知道标识符是不明确的,但警告通常是隐藏的。使用编译器标志来显示警告,在 GCC-Wall -Wextra中对通常的编程最有用:

test.cc: 在函数 »int main(int, char**)«:
test.cc:5:43:警告:未知转换符号 »z« 格式为 [-Wformat]
test.cc:5:43:警告:格式的许多参数 [-Wformat-extra-args]
test.cc:全球:
test.cc:3:5:警告:未使用的参数 »argc« [-Wunused-parameter]
test.cc:3:5:警告:未使用的参数 »argv« [-Wunused-parameter]
test.cc:2:13:警告:»T« 已定义,但未使用 [-Wunused-variable]

在这种情况下,我们会看到全局static char T已定义,但从未使用过。

于 2012-10-11T05:54:22.413 回答
1

在 C 中,当声明一个结构时,它是类型的struct <name of struct>,而不仅仅是结构的名称。这就是原因。为了避免混淆,人们使用typedef简化 C 中的声明

于 2012-10-11T07:53:51.033 回答
0

正如其他人所提到的,在第一个片段中,本地struct T将隐藏静态变量C++。但是,要完全了解发生了什么,您还必须谈论名称消歧。在第二个代码片段中,struct T没有隐藏T——它们在同一个范围内。

于 2012-10-11T05:58:55.957 回答