用c ++和c命名空格

时间:2011-09-29 12:55:04

标签: c++ c syntax

并非我在我的专业工作中编写如下代码,以下代码是合法的,并在c ++和c中编译而没有警告:

#include <stdlib.h>

typedef struct foo { int foo; } foo;

foo * alloc_foo () {
   return (struct foo*) malloc(sizeof(foo));
}   

struct foo * alloc_struct_foo () {
   return (foo*) malloc(sizeof(struct foo));
}   


foo * make_foo1 (int val) {
   foo * foo = alloc_struct_foo (); 
   foo->foo = 0;
   return foo;
}

struct foo * make_foo2 (int val) {
   struct foo * foo = alloc_foo();
   foo->foo = 0;
   return foo;
}

C中的这个合法且明确的含义是C标准的第6.2.3节:

  

6.2.3标识符的名称空间
  如果在翻译单元中的任何点处可见多于一个特定标识符的声明,则句法上下文消除了引用不同实体的用法。因此,各种类别的标识符(标签名称,结构,联合和枚举的标签,结构或联合的成员;以及普通标识符)都有单独的名称空间。

请注意,由于生活在自己名称空间中的标签名称,我可以通过在某处使用标签foo使代码更加模糊。

添加以下代码并且代码无法编译:

int foo (foo * ptr) {
   return ++ptr->foo;
}   

所以,有两个问题,一个与C和C ++有关,另一个与C ++相关。

  • C / C ++问题:为什么我不能定义函数foo
    我似乎应该能够定义函数foo;函数名和变量名是“普通标识符”。但如果我添加最后一点代码,我会得到error: redefinition of 'foo' as different kind of symbol 问题:foo * foo;完全合法,为什么int foo (foo*);不合法?

  • C ++问题:这在C ++中是如何工作的? “名称空间”的含义在C ++中的含义与在C中的含义截然不同。我在C ++标准中找不到任何关于名称空间的C概念的内容,这就是上述内容在C语言中的合法性。
    问题:在C ++中这是合法的(章节和诗歌首选)?

4 个答案:

答案 0 :(得分:8)

  

foo * foo;完全合法,那么为什么int foo (foo*);不合法?

因为在与函数相同的声明上下文中已存在名为foo的类型。您不能在同一范围内拥有同名的类型和函数。

  

这在C ++中是如何工作的?

因为您可以隐藏嵌套作用域中的名称。当您声明foo * foo时,第一个foo引用该类型。第二个foo声明一个变量 - 此时隐藏了foo类型。尝试在foo * baz之后声明foo * foo,它应该会失败。

struct foo {};

void test() {
   foo * foo; // first `foo` is the type, second `foo` is the variable
   foo * baz; // first `foo` is the variable
}

答案 1 :(得分:1)

在C ++ 11中,3.3.1 / 4表示在声明性区域中,名称的所有声明都必须引用同一个实体(或重载集)。有一个例外允许你为一组函数名使用类名(所以foo()隐藏class foo)但如果你有一个typedef(你这样做),这不适用。

尝试使用C ++中省略的typedef struct foo foo

答案 2 :(得分:0)

这在C ++中也不起作用......问题是gcc / g ++的预处理器正在寻找__cplusplus,而不是cplusplus。因此你预处理器语句

#if defined FOO && ! defined cplusplus
#undef FOO
#endif

无法正常工作。

答案 3 :(得分:0)

因为已经有foo()函数,所以它是struct foo的默认构造

typedef struct foo 
{ 
int a; 
foo(int val)
:a(val) 
{}
} foo;


int foo(int value)
{
  cout << value <<endl;
}

void main()
{
   foo foovar = foo(50); // constructor foo or function foo?
}

C中没有构造函数这样的东西。

专为Alan Stokes编辑:

typedef struct foo
    { 
    int a; 
    foo(int val, double val2)
    :a(val) 
    {
      cout << val2 << endl;
    }
    } foo;


    int foo(int value, double val2)
    {
      cout << value << val2 << endl;
    }

    void main()
    {
       some_random_func(foo(50, 1.0)); // constructor foo or function foo?
    }