我需要社区帮助解决使用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
,则问题不会改变。
答案 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中使用。当然,如果没有,则必须命名中间的嵌入式结构。正如第一段所述,这很优雅,并且在使用旨在支持将来更新且问题最少的第三方代码时特别有用。