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

g++ compile error on C nested struct

我需要社区的帮助来解决有关使用 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 中,嵌套结构没有被任何作用域语法引用,而是被称为好像它们没有嵌套。也就是说,我非常有信心我可以像在 staticFuncs.h 中那样做 struct Inner* ptr = NULL;。比我的信心更重要的是,如果我用 cc 而不是 g++ 编译,编译就会通过。

我尽我最大的努力告诉 g++ 我正在编译 C,而不是 C++,通过在各处添加 extern "C" 代码,但它是仍然被 Inner.

的范围所绊倒

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

如果 staticFuncs.h 改为 staticFuncs.c,问题没有改变。

如果静态函数不是静态的,问题没有改变。

如果 staticFuncs.h/c 的内容嵌入 ns.c 而不是 #includeed,问题没有改变。

编译器的错误信息很清楚。

赋值运算符的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;

虽然 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;

我正在开发一个项目,该项目在默认设置下使用 g++ 进行编译,无需更改(总结)。我在添加 SQLite3 Amalgamation 文件时遇到了同样的问题,即 C 代码。为了在更新此文件以合并官方 SQLite3 更改时尽量减少 Git 上的冲突,您还可以添加以下技巧,以我的案例为例:

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

紧跟在嵌入_ht结构的结构(Hash)之后,这肯定会在以后的LHS中使用。当然,如果中间嵌入结构不是,则必须命名它们。这很优雅,并且在使用旨在以最少的问题支持未来更新的第三方代码时特别有用,正如第一段中所推理的那样。