C/C++ usage of typedef struct

J

Josh

I'm trying to define a data type that is an array of structures. I
have borrowed the following C code, which appears in a textbook by Aho
and Ullman:

typedef struct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

While g++ doesn't object to this definition, the first time we try to
use GRAPH as a parameter in a function prototype g++ complains that the
"non-local function...uses anonymous type." I can only assume this is
caused by differences between C and C++. Any ideas for how I can
implement the desired array of structures? Your help would be
appreciated.

Best Regards,
Josh
 
T

Thomas Tutone

Josh said:
I'm trying to define a data type that is an array of structures. I
have borrowed the following C code, which appears in a textbook by Aho
and Ullman:

typedef struct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

While g++ doesn't object to this definition, the first time we try to
use GRAPH as a parameter in a function prototype g++ complains that the
"non-local function...uses anonymous type." I can only assume this is
caused by differences between C and C++. Any ideas for how I can
implement the desired array of structures? Your help would be
appreciated.

At the most basic level, like this:

struct Item {
float dist;
LIST successors;
POTNODE toPOT;
};

Item graph[MAX];

Better yet, make Item into a class and design an interface so that its
data members are not public, and then use a std::vector or other
container from the standard library rather than using an array. If
that makes no sense to you, you need to get a good book introducing
C++. I recommend Accelerated C++ by Koenig and Moo.

Best regards,

Tom
 
J

Jim Langston

Josh said:
I'm trying to define a data type that is an array of structures. I
have borrowed the following C code, which appears in a textbook by Aho
and Ullman:

typedef struct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

While g++ doesn't object to this definition, the first time we try to
use GRAPH as a parameter in a function prototype g++ complains that the
"non-local function...uses anonymous type." I can only assume this is
caused by differences between C and C++. Any ideas for how I can
implement the desired array of structures? Your help would be
appreciated.

Best Regards,
Josh

This is an unnamed type. The structure doesn't have a name. So give it
one. Incidently, you can get rid of the typedef in C++.

struct GraphStruct{
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

Now this structure has a name, GraphStruct.

This is the simplest way to fix it.
 
J

Josh

Jim said:
struct GraphStruct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

Thanks, Jim. I changed the structure definition to read

struct GRAPH {
float dist;
LIST successors;
POTNODE toPOT;
} graph[MAX];

This works well enough, but it's not exactly what I had in mind. Is
there a way to define a structure that is an array in which each
element has multiple members as above?

Best Regards,
Josh

P.S. I should also mention I would prefer to implement without the use
of container classes from the standard library.
 
O

Old Wolf

Josh said:
I'm trying to define a data type that is an array of structures.

Usually a bad idea; it can lead to obfuscated code.
I have borrowed the following C code, which appears in a
textbook by Aho and Ullman:

typedef struct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

This is similar to:

struct _unnamed {
float dist;
/* etc */
};

typedef struct _unnamed GRAPH[MAX];

except that the struct has no name at all.
While g++ doesn't object to this definition, the first time we try to
use GRAPH as a parameter in a function prototype g++ complains that the
"non-local function...uses anonymous type." I can only assume this is
caused by differences between C and C++.

C++ does not allow you to declare an externally-visible function
that accepts an anonymous type as parameter -- presumably
because there is no way this function can be called externally!
Any ideas for how I can implement the desired array of structures?
Your help would be appreciated.

The easiest fix is to give your struct type a name, ie. stick something
after the keyword "struct" and before the open brace.

The second-easiest is to declare the function as having internal
linkage (eg. by prefixing the declaration with "static", or putting
it in an anonymous namespace).

Personally I would suggest you avoid the typedef entirely, and
write out the array parameter as you need it.
 
O

Old Wolf

Josh said:
struct GRAPH {
float dist;
LIST successors;
POTNODE toPOT;
} graph[MAX];

This works well enough, but it's not exactly what I had in mind. Is
there a way to define a structure that is an array in which each
element has multiple members as above?

With this new defintion of GRAPH, the line:
GRAPH graph[5][MAX];

has the same effect as this would have with your original definition:
GRAPH graph[5];

and it is more obvious what the code is doing.
 
F

Frederick Gotham

Josh posted:
typedef struct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

Firstly, only use CAPSLOCK for macro names.

Change it to:

struct MyStruct {
float dist;
List successors;
PotNode toPot;
};

typedef MyStruct Graph[MAX];

Or, if you want to retain compatibility with C:

typedef struct MyStruct {
float dist;
List successors;
PotNode toPot;
} MyStruct;

typedef MyStruct Graph[MAX];
 
B

Bart

Josh said:
Jim said:
struct GraphStruct {
float dist;
LIST successors;
POTNODE toPOT;
} GRAPH[MAX];

Thanks, Jim. I changed the structure definition to read

struct GRAPH {
float dist;
LIST successors;
POTNODE toPOT;
} graph[MAX];

This works well enough, but it's not exactly what I had in mind. Is
there a way to define a structure that is an array in which each
element has multiple members as above?

You can typedef the array type, but I wouldn't recommend it. Unless
you're dealing with a bunch of legacy C code, the only time I can see
that kind of construct as being useful is for something that never
changes size, like say a hardware descriptor table. This certainly does
not appear to be the case here. But even then the typedef only
obfuscates the code. It is better to have clarity at the point of use
than at the point of declaration.
P.S. I should also mention I would prefer to implement without the use
of container classes from the standard library.

Your reasons may well be valid, but in general excuses for not using
the standard library are rather poor. Perhaps you would like to tell us
what you're really trying to do?

Regards,
Bart.
 
J

Josh Zenker

Frederick said:
struct MyStruct {
float dist;
List successors;
PotNode toPot;
};

typedef MyStruct Graph[MAX];

Or, if you want to retain compatibility with C:

typedef struct MyStruct {
float dist;
List successors;
PotNode toPot;
} MyStruct;

typedef MyStruct Graph[MAX];

Thanks for bearing with my inexperience, guys. I think I'm going with
the code suggested by Frederick and several others.

Bart, if you still want to know where this code is being used, it's an
implementation of Dijkstra's algorithm for shortest paths.

-Josh
 
B

Bart

Josh said:
Bart, if you still want to know where this code is being used, it's an
implementation of Dijkstra's algorithm for shortest paths.

I figured it's something like that. Now, Aho & Ullman may be
respectable authors when it comes to algorithms, but that doesn't mean
you should copy their code blindly. In fact, textbook code is usually
not the best example to follow for writing real code, especially C
textbook code in a C++ program.

Just my two cents.

Regards,
Bart.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top