can someone tell me if I'm going insane.

Discussion in 'C Programming' started by thomas.luce@gmail.com, Jun 20, 2006.

  1. Guest

    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
     
    , Jun 20, 2006
    #1
    1. Advertising

  2. Eric Sosman Guest

    wrote On 06/20/06 12:45,:
    > 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.

    --
     
    Eric Sosman, Jun 20, 2006
    #2
    1. Advertising

  3. Guest

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

    Thanks again,
    -Thomas

    Eric Sosman wrote:
    > wrote On 06/20/06 12:45,:
    > > 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.
    >
    > --
    >
     
    , Jun 20, 2006
    #3
  4. 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;
    }



    --

    Frederick Gotham
     
    Frederick Gotham, Jun 20, 2006
    #4
  5. writes:
    > 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.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jun 20, 2006
    #5
  6. On 20 Jun 2006 09:45:05 -0700, wrote:

    >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
     
    Barry Schwarz, Jun 21, 2006
    #6
  7. Old Wolf Guest

    wrote:
    >
    > 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.
     
    Old Wolf, Jun 21, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    335
  2. Dildo Boy
    Replies:
    6
    Views:
    344
    Flash Gordon
    Mar 6, 2007
  3. E-Dot
    Replies:
    15
    Views:
    550
  4. homerjk
    Replies:
    4
    Views:
    495
    homerjk
    Mar 8, 2007
  5. ASF
    Replies:
    0
    Views:
    271
Loading...

Share This Page