473,396 Members | 1,940 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Errors with typedefs

Hi,

I am currently working on a Pascal-to-C translation, and I am getting an
error that I can't seem to debug.

I have a globals.h file, and here is a snippet from it:

--

typedef char ShortString[100];

typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
};

typedef struct SpellRec* SpellTableEntry;

--

Then, I have the following function in one of my .c files:

--

SpellTableEntry NewSpell(ShortString na, TokenKind k,
SpellTableEntry ne) {

SpellTableEntry spell = (SpellTableEntry)malloc(sizeof(SpellTableEntry));
spell->name = na;
spell->kind = k;
spell->symbol = NULL;
spell->next = ne;
return spell;
} /* NewSpell */

--

I get the following errors:
scanner.c:20: error: syntax error before "TokenKind"
scanner.c: In function 'NewSpell':
scanner.c:24: error: incompatible types in assignment
scanner.c:25: error: 'k' undeclared (first use in this function)
scanner.c:25: error: (Each undeclared identifier is reported only once for
each function it appears in.)
scanner.c:27: error: 'ne' undeclared (first use in this function)

Does anyone have any clue how I could fix this? I am at my wits end, and any
help is greatly appreciated.

TIA,
Erica

Nov 14 '05 #1
6 1930

"Erica" <er***@nospam.com> wrote in message
news:1098169095.K2tmnLiVH/9l9BIQRZQcWw@teranews...

Not very difficult... A Question of syntax.

<snip>
typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
};


You now have a anonymous type and a structure called SpellRec. Compare, for
instance,

struct foobar
{
...
};

and

struct
{
...
} foobar;

The first defines a structure, the second a variable.

Try

typedef struct
{
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
} SpellRec ;

You now have a type called SpellRec with an anonymoust structure as
"content".

HTH.

dandelion.
Nov 14 '05 #2
"Erica" <er***@nospam.com> wrote in message
news:1098169095.K2tmnLiVH/9l9BIQRZQcWw@teranews...
Hi,

I am currently working on a Pascal-to-C translation, and I am getting an
error that I can't seem to debug.

I have a globals.h file, and here is a snippet from it:

--

typedef char ShortString[100];
Ok, fine. ShortString is typedef name that is
an alias for char[100] type.

typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
};

typedef struct SpellRec* SpellTableEntry;

Try changing the above to:

typedef struct SpellRec* SpellTableEntry;

typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
SpellTableEntry next;
} SpellRec;

I've defined the struct pointer name before
the struct itself. I've used the struct pointer
name within the struct. Finally, I've given
the struct a typedef name.

/snip/

Nov 14 '05 #3
Hmmm...I tried that, and I still get the same errors. I don't think that the
problem is with the SpellRec, but rather the arguments that I'm passing to
the function.

Here is the definition of ShortString:

typedef char ShortString[100];

Here's TokenKind:

enum TokenKind {tInvisibleToken,
tIdent,
tIntNum, tRealNum,
tEND, tREAL, tINTEGER,
tARRAY, tFUNCTION, tPROCEDURE, tRETURN, tVAR,
tIF, tTHEN, tELSE, tWHILE, tDO, tREAD, tWRITE,
tAND, tOR, tNOT,
tPeriod, tSemicolon, tComma, tAssign,
tPlus, tMinus, tTimes, tDivide,
tEq, tNotEq, tLess, tLessEq, tGtr, tGtrEq,
tLParen, tRParen
};

And SpellTableEntry:
typedef struct SpellRec* SpellTableEntry;

Thanks though!!
--Erica
Nov 14 '05 #4
In article <1098169095.K2tmnLiVH/9l9BIQRZQcWw@teranews>, Erica
<er***@nospam.com> wrote:
Hi, I am currently working on a Pascal-to-C translation, and I am getting an
error that I can't seem to debug. I have a globals.h file, and here is a snippet from it: -- typedef char ShortString[100]; typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
};
The above typedef is wrong. You need to either drop the typedef and make
it a plain struct SpellRec {, or you need to add the name to typedef to
after the closing curly bracket. So
typedef struct SpellRec { char name[12]; enum TokenKind kind;
SymbolTableEntry symbol; struct SpellRec* next;
} SpellRec;

typedef struct SpellRec* SpellTableEntry; -- Then, I have the following function in one of my .c files: -- SpellTableEntry NewSpell(ShortString na, TokenKind k, SpellTableEntry
ne) {
You have not provided a definition for TokenKind, or enum TokenKind, but
presuming that they are both the same thing and they are not typedefed
then you will need to add the enum key word to this function declaration
so you will have:

SpellTableEntry NewSpell(ShortString na, enum TokenKind k, SpellTableEntry
ne) {
SpellTableEntry spell =
(SpellTableEntry)malloc(sizeof(SpellTableEntry)); spell->name = na;
The above line is wrong, as you cannot copy strings using the equals
operator. You need to either use a library routine to copy the string, or
copy the string character by character, or change name to a pointer to a
char. Taking the first option gives you (and making sure not to copy more
characters than name can hold, and making sure to include string.h at the
top of the file):

strncpy( spell->name, na, sizeof(spell->name)-1); spell->name[
sizeof(spell->name)-1] = '\0';
spell->kind = k;
spell->symbol = NULL;
spell->next = ne;
return spell;
} /* NewSpell */
Does anyone have any clue how I could fix this? I am at my wits end, and
any help is greatly appreciated.


The three changes I have suggested above should fix them.

Kevin

Nov 14 '05 #5
Others have addressed the "typedef int /* no alias here */;" issue:
typedef's syntax is funky, in that it takes the existing type, then
a series of variable declarations, and changes the variable declarations
into alias-declarations instead.

No one has, however, directly mentioned the more important thing:
C's "typedef" does not define types at all.

C's "struct" (and "union" and "enum" keywords as well, but they
are "lesser", as it were) is what actually declares new types.

Unlike Pascal, where you really want to declare a bunch of types
first, then use them in variable declarations, C lets you mix everything
together. It does this by requiring the "struct" keyword each time.
Just think of "struct" as meaning "type" and you will be fine. :-)

Similarly, you need the word "enum" to mean "(enumerated) type", when
referring back to an enumeration. In Pascal you would make up type
names for your records and enumerations, and then use those; in C,
you do them all at once:

In article <news:1098169095.K2tmnLiVH/9l9BIQRZQcWw@teranews>
Erica <er***@nospam.com> wrote:
typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
};
If you drop the "typedef" entirely, you will have:

struct SpellRec { ...contents... };

which defines a type named "struct SpellRec" (complete with the
"struct" keyword). This contains something of type "char [12]",
then something of type "enum TokenKind" (complete with the "enum"
keyword), then something of type "SymbolTableEntry" (no keyword --
must be a typedef-alias for some other "real" type), then something
of type "struct SpellRec *" (pointer to struct SpellRec, using the
"struct" keyword).

Except in a few peculiar corner cases involving <stdarg.h>, you
never *need* the typedef keyword at all, in C. You may decide
that you like it -- especially if you have been programming in
Pascal -- but you need to learn, deep in your gut as it were,
that typedef does not create types. If you write, for instance:

typedef double Temperature;
typedef double Area;

you probably want to prevent people from doing silly things like:

Temperature t;
Area a;
...
a = t; /* same area as a temperature (?!?) */

In C, though, typedefs are just aliases. "a" and "t" are really
both just "double"s, just as if you had written:

double t;
double a;

and therefore "a = t" is a perfectly good assignment.

To create new types, so that "a = t" becomes an error, you have
to encapsulate your data inside a "struct" (or union, or -- except
that enumerations are just integers -- enum):

struct temperature { double val; };
struct area { double val; };
...
struct temperature t;
struct area a;
...
a = t; /* error, and a C compiler must emit a diagnostic */

Although the structures have the same "shape" (one double) and
element-names ("val"), they are different types, and you cannot
pass a "struct temperature" where a "struct area" is required,
for instance.
typedef char ShortString[100];
typedef struct SpellRec* SpellTableEntry;
These just make aliases for the existing types "char [100]" (array
of size 100 of char) and "struct SpellRec *" (pointer to struct
SpellRec).

Note that you can make an alias for a structure type before
defining the (new) structure type:

typedef struct newtype alias_for_newtype;
struct newtype { ...contents... };

In general, I prefer not to use such typedefs at all, but this is
a matter of taste (I know chocolate is better than vanilla, and
dark chocolate better than milk chocolate, but I realize other
people believe otherwise, no matter how wrong they are :-) ).
Then, I have the following function in one of my .c files:

SpellTableEntry NewSpell(ShortString na, TokenKind k,
SpellTableEntry ne) {

SpellTableEntry spell =
(SpellTableEntry)malloc(sizeof(SpellTableEntry) );
spell->name = na;
spell->kind = k;
spell->symbol = NULL;
spell->next = ne;
return spell;
} /* NewSpell */

--

I get the following errors:
scanner.c:20: error: syntax error before "TokenKind"
This is because there is no typedef-alias named "TokenKind".

Your structure uses a type named "enum TokenKind", and presumably
this is what "k" should be, so the function should read:

struct SpellRec *NewSpell(char na[100], enum TokenKind k,
struct SpellRec *ne) {
...
}

(or put in some or all of your typedef-aliases if you prefer
them).

Note that the "value" of an array is a pointer to its first element,
and "na" is declared as if it were an array. Since C always passes
by value (there is nothing directly equivalent to Pascal's "var";
you have to simulate it with pointers), a C function that *appears*
to take an array as a paremter actually receives a pointer to the
array's first element. (See also <http://web.torek.net/torek/c/pa.html>
and "The Rule" about arrays and pointers in C.) Thus, I would
actually change the above even a bit more, to read:

struct SpellRec *NewSpell(char *na, enum TokenKind k,
struct SpellRec *ne) {
...
}

Because arrays have this peculiar behavior when passed as parameters,
I think one should *never* use a typedef to make an alias for an
array type. It is not that you cannot make this work, it is just
that, without knowing whether "T" is the name of an array type, you
cannot predict how a parameter of type "T" behaves.

The remaining errors:
scanner.c: In function 'NewSpell':
scanner.c:24: error: incompatible types in assignment
scanner.c:25: error: 'k' undeclared (first use in this function)
scanner.c:25: error: (Each undeclared identifier is reported only once for
each function it appears in.)
scanner.c:27: error: 'ne' undeclared (first use in this function)


are just "cascades" produced because of the first error.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #6
Erica <er***@nospam.com> wrote:

typedef char ShortString[100];

typedef struct SpellRec {
char name[12];
enum TokenKind kind;
SymbolTableEntry symbol;
struct SpellRec* next;
};
When you write:
struct SpellRec { .... };
you declare a type called "struct SpellRec". At this point,
the compiler would not recognize the name "SpellRec" unless
it was preceded by "struct".

When you write:
typedef SOMETHING SpellRec;
you declare an alias "SpellRec" that means the same as an
existing type.

So, what you wrote is invalid syntax. It is like writing:
typedef int;

You could write:

struct SpellRec { ...... };
typedef struct SpellRec SpellRec;

or, identically, combine the two as:

typedef struct SpellRec { ....... } SpellRec;

Then "struct SpellRec" is a type, and "SpellRec" by itself
is an alias for that type.
This doesn't cause confusion to the compiler, there are
different namespaces for struct tags as for type aliases.
[Note - here I am going to place the compiler error messages
you wrote, after the line that it applies to]
typedef struct SpellRec* SpellTableEntry;

SpellTableEntry NewSpell(ShortString na, TokenKind k,
SpellTableEntry ne) {

scanner.c:20: error: syntax error before "TokenKind"
You must have declared TokenKind as:
enum TokenKind { ..... };
That means you have to refer to it as "enum TokenKind" everywhere
(as you correctly did in the declaration of SpellRec).

This is similar to your problem with declaring "struct SpellRec".
If you want to have a type alias "TokenKind" on its own then go:

enum TokenKind { ........ };
typedef enum TokenKind TokenKind;
or just
typedef enum TokenKind { ......... } TokenKind;

SpellTableEntry spell =
(SpellTableEntry)malloc(sizeof(SpellTableEntry));
You malloc'd the wrong number of bytes, this is an example of
why most people dislike pointer typedefs. You need to malloc
the size of a SpellRec struct. Also it is silly to cast the
return value of malloc. Instead:

SpellRec *spell = malloc(sizeof *spell);

Make sure you had "#include <stdlib.h>" at the start of the file.
spell->name = na;

scanner.c: In function 'NewSpell':
scanner.c:24: error: incompatible types in assignment
You can't use '=' to assign arrays, unfortunately.
You have to be especially careful with this case, because
"name" is a char[12] but "na" is a (char *) which probably
points to an array of size 100. So you have to copy at
most 12 bytes out of "na", and make sure that "name" gets
0-terminated correctly. (If you don't understand what I
just wrote then go and read the FAQ section on C string
handling).
My preferred way to do this is:

snprintf(spell->name, sizeof spell->name, "%s", na);

although if your system does not have snprintf you can go:

strncpy(spell->name, na, sizeof spell->name);
spell->name[sizeof spell->name - 1] = '\0';
spell->kind = k;
spell->symbol = NULL;
spell->next = ne;

scanner.c:25: error: 'k' undeclared (first use in this function)
scanner.c:27: error: 'ne' undeclared (first use in this function)


These errors should go away when you fix the TokenKind problem,
they occurred because the compiler stopped reading the function
parameters when it couldn't understand 'TokenKind'.
Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Levent | last post by:
Please consider the following Parent and Child template classes: template <class T> class Parent { public: typedef T type; typedef T& ref; /* pack of typedefs */ };
0
by: Steven T. Hatton | last post by:
I copied what I believe is a complete representation of <iosfwd> from ISO/IEC 14882:2003(E). My understanding of the rules covering typedefs, templates and forward declarations is not very solid. ...
9
by: bubbakittee | last post by:
I am designing a package of functions to be used by people with very little programming experience (if any) and very little patience. I don't want to scare them with programmerish words like...
1
by: Michal Wróbel | last post by:
Hello, I've got few questions concerning typedefs inside class definition. Firstly, I'll give an example code: template< class T > class Function { public: typedef boost::shared_ptr<...
30
by: junky_fellow | last post by:
I was looking at the source code of linux or open BSD. What I found that lots of typedefs were used. For example, consider the offset in a file. It was declared as off_t offset; and off_t is...
7
by: Noah Roberts | last post by:
I have something like the following: template<ENUM X, int I = 0> class Generic { .... }; typedef Generic<Val1> v1_type; typedef Generic<Val2> v2_type;
2
by: =?Utf-8?B?VGhlQ3VyaW91c09uZQ==?= | last post by:
I have this situation where I need to access the #defines and typedefs defined in a C++ header file from a .NET Project (specifically C#). The C++ header file is from a medical device manufacturer...
1
by: pauldepstein | last post by:
While reading some source code, I saw a variable called "end" of type "time". So I investigated what the type "time" meant and saw that time was a typedef for "Real". So what does "Real" mean? ...
4
by: (2b|!2b)==? | last post by:
template <typename T1, typename T2> struct MyDbInfo { MyDbInfo():m_pEnv(0), m_tran(0), m_db(0), m_idx(0) {} MyDbInfo(CDbEnv *env, DbTxn* tran, T1* db_ptr, T2 *idx_ptr):m_pEnv(env),...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.