can someone tell me if I'm going insane.

T

thomas.luce

Okay, I have been programming for a long time, and am getting back into
C after about a 4 year break from it. Below is some code that won't
compile for the life of me, and it is driving me crazy! If anyone can
see anything that I can't, I would love to know. All the code is
pasted, although in my real code it is broken into a header and a
seperate .c file.

#include <stdlib.h>

typedef enum {typeNum, typeString} VariableType;

typedef struct variableTag {
int id;
VariableType type;
union {
double nValue;
char *sValue;
};
} Variable;

#define VAR_SIZE = sizeof(int) + sizeof(VariableType) + sizeof(double)
+ sizeof(char*);

int num_vars = 0;
Variable *my_vars;
my_vars = (Variable *)malloc(100 * sizeof(Variable));

/*
* Make a variable and return a pointer to it.
*/
struct Variable *make_var(char *name) {
//TODO: do this.
}


Seems simple, right? (this is part of a lex/yacc compiler I am working
on). When I compile it, here is what I get:
file.c:6: error: conflicting types for 'my_vars'
file.c:5: error: previous declaration of 'my_vars' was here
file.c:6: warning: initialization makes integer from pointer without a
cast
file.c:6: error: initializer element is not constant
file.c:6: warning: data definition has no type or storage class

Just for a sanity check I tried this:
int *p;
p = malloc(sizeof(int) * 100);

Same errors. Am I going crazy? Is there something horribly simple that
I have forgotten about C in the last few years?

Any help is much appreciated!
Thanks,
-Thomas
 
E

Eric Sosman

Okay, I have been programming for a long time, and am getting back into
C after about a 4 year break from it. Below is some code that won't
compile for the life of me, and it is driving me crazy! If anyone can
see anything that I can't, I would love to know. All the code is
pasted, although in my real code it is broken into a header and a
seperate .c file.

#include <stdlib.h>

typedef enum {typeNum, typeString} VariableType;

typedef struct variableTag {
int id;
VariableType type;
union {
double nValue;
char *sValue;
};
} Variable;

#define VAR_SIZE = sizeof(int) + sizeof(VariableType) + sizeof(double)
+ sizeof(char*);

int num_vars = 0;
Variable *my_vars;
my_vars = (Variable *)malloc(100 * sizeof(Variable));

/*
* Make a variable and return a pointer to it.
*/
struct Variable *make_var(char *name) {
//TODO: do this.
}


Seems simple, right? (this is part of a lex/yacc compiler I am working
on). When I compile it, here is what I get:
file.c:6: error: conflicting types for 'my_vars'
file.c:5: error: previous declaration of 'my_vars' was here
file.c:6: warning: initialization makes integer from pointer without a
cast
file.c:6: error: initializer element is not constant
file.c:6: warning: data definition has no type or storage class

Just for a sanity check I tried this:
int *p;
p = malloc(sizeof(int) * 100);

Same errors. Am I going crazy? Is there something horribly simple that
I have forgotten about C in the last few years?

You've forgotten that executable statements (as
opposed to declarations and definitions) can only
appear inside function bodies.
 
T

thomas.luce

Sone of a ..... Thanks. I knew it would be something stupid like that.

Thanks again,
-Thomas
 
F

Frederick Gotham

The following compiles for me:


#include <stdlib.h>

typedef enum {typeNum, typeString} VariableType;

typedef struct variableTag {

int id;

VariableType type;

union {
double nValue;
char *sValue;
};

} Variable;


#define VAR_SIZE sizeof(int)\
+ sizeof(VariableType)\
+ sizeof(double)\
+ sizeof(char*)


int num_vars = 0;



Variable *my_vars;


struct Variable *make_var(char *name)
{
return malloc( sizeof(Variable) );
}


void PerformGlobalInitialisations(void)
{
my_vars = malloc(100 * sizeof(Variable));
}


int main(void)
{
PerformGlobalInitialisations();

return 0;
}
 
K

Keith Thompson

Okay, I have been programming for a long time, and am getting back into
C after about a 4 year break from it. Below is some code that won't
compile for the life of me, and it is driving me crazy! If anyone can
see anything that I can't, I would love to know. All the code is
pasted, although in my real code it is broken into a header and a
seperate .c file.

#include <stdlib.h>

typedef enum {typeNum, typeString} VariableType;

typedef struct variableTag {
int id;
VariableType type;
union {
double nValue;
char *sValue;
};
} Variable;

#define VAR_SIZE = sizeof(int) + sizeof(VariableType) + sizeof(double)
+ sizeof(char*);

int num_vars = 0;
Variable *my_vars;
my_vars = (Variable *)malloc(100 * sizeof(Variable));

/*
* Make a variable and return a pointer to it.
*/
struct Variable *make_var(char *name) {
//TODO: do this.
}

Somebody already mentioned that you have statements outside any
function, which is a no-no. You have some other problems as well.

Your macro definition is incorrect. A macro definition doesn't
require "=" or ";" (if it has them, they're just part of the
definition). And this one line-wrapped when you posted it, creating
another syntax error.

If you wanted this macro at all, it should be:

#define VAR_SIZE ( sizeof(int) + \
sizeof(VariableType) + \
sizeof(double) + \
sizeof(char*) )

(Or you could put it all on one line, but not for Usenet.) I've
dropped the "=" and ";", and enclosed the entire thing in parentheses.

Study this program to understand why you want lots of parentheses in a
macro definition:
========================================
#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}
========================================

But you almost certainly don't want that macro at all. You don't use
it in your code, but it appears to be attempting to compute the size
of your type "struct variableTag" or "Variable". In fact, the
compiler is free to insert padding between structure members, or after
the last one, so it's impossible to reliably compute the size of a
structure given the sizes of its members. Fortunately, you don't have
to; just use "sizeof(Variable)" (which you've done anyway).

You have an anonymous union in your struct declaration. This is not
allowed in standard C. (gcc allows it as an extension; compile with
"gcc -ansi -pedantic -Wall -W -O3" to diagnose errors like this;
replace "-ansi" with "-std=c99" to compile (most of) C99.)

These lines:
Variable *my_vars;
my_vars = (Variable *)malloc(100 * sizeof(Variable));
would be better written as:
Variable *my_vars;
my_vars = malloc(100 * sizeof *my_vars);

Never cast the result of malloc(). malloc() returns void*, which can
be implicitly converted to any pointer-to-object type, so the cast
isn't necessary. Casting can mask certain errors, such as failing to
include <stdlib.h> or compiling C with a C++ compiler (C++ doesn't do
this implicit conversion, but you probably wouldn't use malloc() in
C++ anyway).

In my opinion, typedefs for structures are rarely useful; they just
create an alias for something that already has a perfectly good name.
Rather than
typedef struct variableTag {
...
} Variable;
I'd simply write:
struct Variable {
...
};
and refer to the type as "struct Variable". (This point is somewhat
controversial; plenty of good C programmers do use this kind of
typedef.)
 
B

Barry Schwarz

Okay, I have been programming for a long time, and am getting back into
C after about a 4 year break from it. Below is some code that won't
compile for the life of me, and it is driving me crazy! If anyone can
see anything that I can't, I would love to know. All the code is
pasted, although in my real code it is broken into a header and a
seperate .c file.

#include <stdlib.h>

typedef enum {typeNum, typeString} VariableType;

typedef struct variableTag {
int id;
VariableType type;
union {
double nValue;
char *sValue;
};
} Variable;

#define VAR_SIZE = sizeof(int) + sizeof(VariableType) + sizeof(double)
+ sizeof(char*);

If you expect this expression (after incorporating Keith's
corrections) to be the size of struct variableTag you may be
surprised. It could be larger or smaller. You use sizeof(Variable)
in you call to malloc so I don't know what you intend this to be.
int num_vars = 0;
Variable *my_vars;
my_vars = (Variable *)malloc(100 * sizeof(Variable));

DON'T cast the ret run from malloc. It can never help and may
suppress diagnostic messages you really want to see.

snip


Remove del for email
 
O

Old Wolf

typedef struct variableTag {
int id;
VariableType type;
union {
double nValue;
char *sValue;
};
} Variable;

struct Variable *make_var(char *name) {
//TODO: do this.
}

As well as what the others wrote: there is no type "struct Variable".
There is "Variable" and "struct variableTag". This confusion
could be avoided by following Keith's suggestion of not
automatically typedeffing every struct.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top