1

我试图编译类似:

struct A
{   int a;
    struct B
    {    int c;
    };
};

现在,当我编译此代码时,编译器会给我一条警告消息:

declaration does not declare anything [enabled by default]

我知道我没有定义任何struct B. 这将意味着我将无法访问 variable c。仍然编译器编译此代码并发出警告。重点是什么?为什么编译器不给出编译错误呢?

添加信息:
的大小struct A等于int我机器上的大小!!

4

4 回答 4

4

因为你可以这样做:

struct A
{   int a;
    struct B
    {    int c;
    };
};

int main()
{
    struct A a = {1};
    struct B b = {2};

    return a.a + b.c;
}

笔记:

  • 声明后需要一个分号B,而您的代码缺少该分号
  • 这不是特别有用,但我想它可能有一些记录目的(即,建议类型之间的关系或分组)
  • 在 C++ 中,第二个变量将具有 type A::B,但 C 没有相同的作用域规则(实际上所有结构都属于全局结构命名空间)

至于允许它的动机......

struct Outer {
    struct {
        int b;
    } anon;
    /* this ^ anonymous struct can only be declared inside Outer,
       because there's no type name to declare anon with */

    struct Inner {
        int c;
    } named;
    /* this ^ struct could be declared outside, but why force it to be
       different than the anonymous one? */

    struct Related {
        double d;
    };
    /* oh no we have no member declared immediately ... should we force this
       declaration to be outside Outer now? */

    struct Inner * (*function_pointer)(struct Related *);
    /* no member but we are using it, now can it come back inside? */

    struct Related excuse;
    /* how about now? */
};

一旦您允许这样的嵌套类型声明,我怀疑是否有任何特殊动机要求立即存在该类型的成员。

于 2012-12-08T18:10:17.620 回答
3

这样做是合法的(但非常糟糕的风格):

struct A {   
    int a;
    struct B {    
        int c;
    };
};
struct B B_instance;
struct A A_instance;

而且编译器不知道后面使用结构类型的变量,所以它真的不应该出错。

于 2012-12-08T18:10:11.100 回答
3

通常,警告意味着代码可能没有按照您的意图执行,但在该语言中是合法的。编译器在说:“这可能不是你真正想做的,但我必须允许你这样做,因为语言说它是允许的。” 由于 C 标准允许,编译器无法为您提供此代码的错误,因此必须允许(除非您专门针对此类事情要求错误,例如使用 GCC 的 -Werror 选项将警告转换为错误)。

C 标准并不试图定义在程序中有意义的所有内容。例如,这些东西在 C 中是合法的:

3;
if (x) then foo(); else foo();
x = 4*0;

第一条语句没有副作用,也没有使用它的返回值。但它在 C 中是合法的,因为语句可能只是一个表达式。第二个语句只是调用foo(),所以if没有意义。在第三个语句中,乘以四是没有意义的。

编写一个禁止所有没有意义的事情的 C 标准将是极其困难的。这当然不值得付出努力。所以这是你回答的一部分:当编写 C 标准的委员会构建语言时,他们是否想花大量时间重写技术规范以排除没有意义的东西?有时是的,如果避免某些可能导致严重错误的事情似乎很有价值。但大多数时候,这不值得他们花时间,而且会使规范不必要地复杂化。

但是,编译器可以识别其中一些内容并警告您。这有助于发现许多印刷错误或其他错误。

另一方面,有时这些结构是由不寻常的情况引起的。例如,一个程序可能有预处理器语句,这些语句struct A在为不同的目标或不同的特性构建时以不同的方式定义。在其中一些目标中,可能不需要struct B成员 in struct A,因此没有声明它,但是struct B(类型,而不是对象)的声明仍然存在,只是因为这样更容易编写预处理器语句。

所以编译器需要允许这些事情,以避免干扰程序员编写各种各样的程序。

于 2012-12-08T19:05:23.267 回答
1

实际上,您在struct B这里声明,但您没有声明该类型的变量。

这是一个警告,但您应该修复它。也许你的意思是:

struct A
{   int a;
    struct B
    {
        int c;
    } c;
};
于 2012-12-08T18:06:41.120 回答