C嵌套结构上的g ++编译错误

时间:2017-08-15 03:47:31

标签: c++ g++ inner-classes

我需要社区帮助解决使用g++编译的C嵌套结构的编译错误。

我有以下三个文件:

main.cpp (为了完整性;不需要此文件来重现编译错误):

#include <iostream>
#include "ns.h"

int main( int argc, char* argv[] )
{
  someFunc();
  return 0;
}

ns.h

#ifndef NS_H
#define NS_H

#ifdef __cplusplus
extern "C" {
#endif

void someFunc();

#ifdef __cplusplus
}
#endif

#endif // NS_H

ns.c

#include "ns.h"

#ifdef __cplusplus
extern "C" {
#endif

#define MY_MAX (42)

typedef struct _outer
{
  int count;
  struct Inner
  {
    int count;
    void* cb;
    void* ctx [ MY_MAX ];
  } inner_[ MY_MAX ];
} Outer;

Outer g_outer[ 10 ];

#include "staticFuncs.h"

void someFunc()
{
  staticFunc();
}

#ifdef __cplusplus
}
#endif

staticFuncs.h

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

static void anotherStaticFunc()
{
  printf( "%s", __FUNCTION__ );

  struct Inner* ptr = NULL;
  ptr = &(g_outer[ 0 ].inner_[ 0 ]);
  (void)ptr;
}

static void staticFunc()
{
  printf( "%s", __FUNCTION__ );
  anotherStaticFunc();
}

#ifdef __cplusplus
}
#endif

相关汇编如下:

>g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


>g++ -g -c ns.c -o ns.o
In file included from ns.c:22:0:
staticFuncs.h: In function 'void anotherStaticFunc()':
staticFuncs.h:12:7: error: cannot convert '_outer::Inner*' to 'anotherStaticFunc()::Inner*' in assignment
   ptr = &(g_outer[ 0 ].inner_[ 0 ]);
       ^

是什么给出了?

我知道在C中,任何作用域语法都没有引用嵌套结构,但是它们被称为嵌套结构。即,我非常有信心,我可以像struct Inner* ptr = NULL;中那样staticFuncs.h。比我信心更重要的是,如果我使用cc而不是g++进行编译,则会进行编译。

我已经尽力告诉g++我正在编译C,而不是C++代码,只是向extern "C"处投掷代码,但它仍在绊倒关于Inner的范围。

任何人都可以帮助确定出现此编译器错误的原因以及我如何解决它?我必须使用g++来编译。

如果staticFuncs.h改为staticFuncs.c,则问题不会改变。

如果静态函数不是静态的,问题就不会改变。

如果staticFuncs.h/c的内容嵌入ns.c而不是#include,则问题不会改变。

3 个答案:

答案 0 :(得分:2)

如果gcc具有某些后缀,gcc会将代码编译为C ++,但是无法用g ++编译C语言。
gcc和g ++之间的唯一区别是后者总是编译C ++,并且它与C ++库链接。

最简单的解决方法是

struct Inner
{
    int count;
    void* cb;
    void* ctx [ MY_MAX ];
};

typedef struct _outer
{
  int count;
  struct Inner inner_[ MY_MAX ];
} Outer;

答案 1 :(得分:1)

编译器的错误消息非常清楚。

赋值运算符的LHS声明为:

struct Inner* ptr = NULL;

该行相当于:

// Declare a struct in the function. This is different from _outer::Inner.
struct Inner;

// Declare the variable using the struct declared in the function.
struct Inner* ptr = NULL;

您需要做的是使用_outer::Inner*作为ptr的类型。

_outer::Inner* ptr = NULL;

答案 2 :(得分:0)

我正在处理一个项目,该项目在默认设置下使用g++进行编译,并且不希望更改(概述)。我在添加C代码的SQLite3 Amalgamation文件时遇到了同样的问题。为了最小化更新此文件以合并官方SQLite3更改时在Git上的冲突,您还可以添加以下技巧,作为我的案例的示例:

#ifdef __cplusplus
#define _ht Hash::_ht
#endif // __cplusplus

紧随嵌入Hash结构的结构(_ht)之后,该结构肯定会在以后的LHS中使用。当然,如果没有,则必须命名中间的嵌入式结构。正如第一段所述,这很优雅,并且在使用旨在支持将来更新且问题最少的第三方代码时特别有用。