-
forward declaration problem C/C++
I have a struct that is shared between a C routine and some C++ code. For the C++ code, it is in a namespace.
Here is the code:
Code:
#ifdef __cplusplus
namespace eth
{
#endif
/**
* This is the structure of the network address table.
* Must be compilable in C and C++.
*/
typedef struct
{
ip_table_entry_t dest[NUM_IP_DESTINATIONS];
} ip_table_t;
#ifdef __cplusplus
} // namespace eth
#endif
As you see, I used the "C" way to make ip_table_t a type.
A C++ class that uses this struct, had the forward declaration:
namespace eth
{
struct ip_table_t;
}
My gcc/g++ (3.3.2) calls this a conflicting declaration. Is this a compiler error?
If I don't try to make it a typedef for C (i.e., leave off the typedef and just declare it struct ip_table_t { ... }, it compiles just fine. But now, of course, when I use it in C, I have to either do a separate typedef or always put "struct" in front when I want to use it.
-
I dont know that this is your best answer, but you can just typedef the array directly:
typedef ip_table_entry_t iptable[NUM_IP_DESTINATIONS];
iptable dest;
C may not like this, I forget what it will let you do. If it will compile, it may simplify your issue and clean up the layers a bit.
------------------------------
You can macro out of your current issue as well:
in the C
#define magictypedef typedef
in the C++
#define magictypedef
and the prototype becomes
magictypedef struct
{ ....
-
You can certainly "typedef" the array, just like in C++.
My real surprise, though, was that forward declaration of structs doesn't work if the struct is declared a type in the C way.
-
Maybe I should ask this: is this valid C++, or is my compiler (gcc) just letting me cheat:
typedef struct { ... } my_struct_type;
as opposed to
struct my_struct_type { ... };
-
 Originally Posted by hendrixj
Maybe I should ask this: is this valid C++, or is my compiler (gcc) just letting me cheat:
typedef struct { ... } my_struct_type;
as opposed to
struct my_struct_type { ... };
Answering this specific question, yes, the code is perfectly legal and in fact, many C programs use this trick to eliminate the use of the keyword struct before a typename. This isn't cheating by the way. You can read more about type names and tag names here:http://www.informit.com/guides/conte...lus&seqNum=412
However, your original example is problematic because of the use of namespaces. You need to use the fully qualified name eth::my_struct_type, not reopen the namespace (which is interpreted as defining a new type).
Danny Kalev
-
is this valid C++, or is my compiler (gcc) just letting me cheat:
typedef struct { ... } my_struct_type;
this is valid C++, but the typedef-name my_struct_type can be used only for linkage purposes.
If the typedef declaration defines an unnamed class (or enum), the first typedef-name declared by the declaration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only ...
if the typedef-name is used where a class-name (or enum-name) is required, the program is ill-formed....
- IS 7.1.3/5
so, the following declaration is an error. (it is also an error in standard C)
Code:
typedef struct { int i ; } typedef_name ;
struct typedef_name ; // C++ - error: typedef_name after struct
// C++ - typedef_name has been previously declared as a typedef
// and not as a struct
however, IS 7.1.3/2 comes to our rescue if we want to use such a construct
In a given scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.
[Example:
typedef struct s { /* ... */ } s;
...
--- end example]
the following declaration is fine (in both C++ and C)
Code:
typedef struct same_typedef_and_struct_name { int i ; } same_typedef_and_struct_name ;
struct same_typedef_and_struct_name ; // C++ - fine: declaration of struct
// C++ - in this context, same_typedef_and_struct_name is the name of a struct
You need to use the fully qualified name eth::my_struct_type, not reopen the namespace (which is interpreted as defining a new type).
this is not required as long as you are only declaring (and not redefining) the struct. the following will compile in both standard C++ and standard C
Code:
#ifdef __cplusplus
namespace eth
{
struct ip_table_t ;
}
#else // C
struct ip_table_t ;
#endif
#ifdef __cplusplus
namespace eth
{
#endif
enum { NUM_IP_DESTINATIONS = 1024 } ;
typedef struct ip_table_entry_t { /* ... */ } ip_table_entry_t ;
typedef struct ip_table_t
{
ip_table_entry_t dest[NUM_IP_DESTINATIONS];
} ip_table_t ;
#ifdef __cplusplus
} // namespace eth
#endif
#ifdef __cplusplus
namespace eth
{
struct ip_table_t ;
}
#else // C
struct ip_table_t ;
#endif
Similar Threads
-
By vb_programmer in forum VB Classic
Replies: 16
Last Post: 06-23-2006, 08:10 AM
-
By Michael in forum ASP.NET
Replies: 14
Last Post: 02-24-2006, 08:54 AM
-
By aesoprock00 in forum Java
Replies: 2
Last Post: 01-28-2006, 06:18 PM
-
Replies: 0
Last Post: 12-13-2001, 12:06 PM
-
By Fabian in forum VB Classic
Replies: 7
Last Post: 06-28-2000, 12:54 PM
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks