0

I've got following code fragment and I want to know if it is pure C or it contains some C++ elements. This question stems from the fact that I think it is only C, but some compilers don't accept the code.

   // User struct derived from FunctionBlock
    struct Function{
        // Inputs
        int codeGenerationIterator;
        int i;
        char* s;
        // Outputs
        // Internal
    };
    void FunctionCall(struct Function *arg){
    }
    void FunctionConstructor(struct Function *arg){
        arg->i=3;
        arg->s="!";
        // Call constructor for all not primitive variables
        // Create struct with first call
        FunctionCall(arg);
    }
    // User type definition
    typedef struct Punto{
        int codeGenerationIterator;
        Function x[3+1];
            Function *x_pointer[3+1];
        double y;
    };
    void PuntoConstructor(struct Punto *arg){
        // Call constructor for all not primitive variables
        for(arg->codeGenerationIterator=0;arg->codeGenerationIterator<=3;arg->codeGenerationIterator++){
            arg->x_pointer[arg->codeGenerationIterator]=&(arg->x[arg->codeGenerationIterator]);
            FunctionConstructor(arg->x_pointer[arg->codeGenerationIterator]);
        }
    }
    // User type definition
    typedef struct Cerchio{
        int codeGenerationIterator;
        double r;
        Punto centro;
            Punto *centro_pointer;
    };
    void CerchioConstructor(struct Cerchio *arg){
        // Call constructor for all not primitive variables
            arg->centro_pointer=&(arg->centro);
        PuntoConstructor(arg->centro_pointer);
    }
    // User type definition
    typedef struct Container{
        int codeGenerationIterator;
        Cerchio circonferenza[10+1];
            Cerchio *circonferenza_pointer[10+1];
    };
    void ContainerConstructor(struct Container *arg){
        // Call constructor for all not primitive variables
        for(arg->codeGenerationIterator=0;arg->codeGenerationIterator<=10;arg->codeGenerationIterator++){
            arg->circonferenza_pointer[arg->codeGenerationIterator]=&(arg->circonferenza[arg->codeGenerationIterator]);
            CerchioConstructor(arg->circonferenza_pointer[arg->codeGenerationIterator]);
        }
    }

    int main(void){

        // Variable definitions
        int codeGenerationIterator;
        int count;
        Punto insiemePunti[50+1];
            Punto *insiemePunti_pointer[50+1];
        Cerchio cerchio;
            Cerchio *cerchio_pointer;
        Container container;
            Container *container_pointer;
        Container containers[11+1];
            Container *containers_pointer[11+1];
        // Call constructor for all not primitive variables
        for(codeGenerationIterator=0;codeGenerationIterator<=50;codeGenerationIterator++){
            insiemePunti_pointer[codeGenerationIterator]=&insiemePunti[codeGenerationIterator];
            PuntoConstructor(insiemePunti_pointer[codeGenerationIterator]);
        }
            cerchio_pointer=&cerchio;
        CerchioConstructor(cerchio_pointer);
            container_pointer=&container;
        ContainerConstructor(container_pointer);
        for(codeGenerationIterator=0;codeGenerationIterator<=11;codeGenerationIterator++){
            containers_pointer[codeGenerationIterator]=&containers[codeGenerationIterator];
            ContainerConstructor(containers_pointer[codeGenerationIterator]);
        }

        container.circonferenza[1].centro.x[0].i=2;
        containers[2].circonferenza[2].centro.x[4].i=2;

    printf("Works!");
    getchar();getchar(); // TODO: delete
    return 0;
    }

As you can see I haven't use classes or overloading but only simple instructions, structs and some pointers. So, why do some strict C compilers give me an error?

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
Tommaso DS
  • 211
  • 2
  • 14

3 Answers3

8

No, this is not valid C. This line:

    Function x[3+1];

lacks the struct keyword, and there's no typedef struct Function Function; to introduce the type alias you seem to be using.

Also, the use of // comments requires a recent-enough compiler, that syntax wasn't added to C officially until C99. An older compiler would fail for this reason, too.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 1
    Well you could say it's non-compiling C that's only missing some `struct` keywords? :P – Jite Dec 13 '12 at 11:58
  • So I had only to add the `struct` keyword before definition of variable? – Tommaso DS Dec 13 '12 at 11:58
  • @TommasoDS The best way is to use `typedef struct {} Function;` because then you get a type naming system that is compatible with C++. Some people prefer to type out struct, for reasons unknown. (For example the Linux kernel coding standard contains a rather fuzzy rationale over why it would be good to write struct all over the place.) – Lundin Dec 13 '12 at 12:03
  • @Lundin Named structs are necessary to create self-referential data structures and for forward declarations. Also, nameless structs look ugly when inspected in `gdb`. – user4815162342 Dec 13 '12 at 12:35
  • @user4815162342 That is not correct, you can either type `typedef struct something { something* x; } something_t;` or declare an incomplete type, ie `struct something;` followed by the actual struct definition. – Lundin Dec 13 '12 at 12:39
  • 1
    @Lundin But in that case you also named the struct. – user4815162342 Dec 13 '12 at 12:40
  • @user4815162342 Yes the struct was given a struct tag, but I don't have to type `struct something` all over my code to use it (even though I could), instead I only have to type `something_t` and my type naming would at the same time be consistent with C++. – Lundin Dec 13 '12 at 12:41
  • @Lundin Also note that type names ending in `_t`, such as `something_t` are [reserved by POSIX](http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html) for the implementation. – user4815162342 Dec 13 '12 at 12:42
  • @Lundin Agreed about not *having* to type `struct something` all the time, I understood your comment to claim that `typedef struct {...} something` was sufficient. – user4815162342 Dec 13 '12 at 12:43
  • @user4815162342 It _is_ sufficient. The odd case when you have a self-referencing struct is a special one. You can still use the typedef notation without stating a struct tag, as long as there is a declaration of an incomplete struct type before the typedef. – Lundin Dec 13 '12 at 12:45
  • @user4815162342 Too bad for POSIX then, since `_t` has been a very common type naming convention in the C language during the past 40 years or so. I guess they'll have to remake the POSIX standard if this C language thing will become successful. – Lundin Dec 13 '12 at 12:46
  • @Lundin, the POSIX standard always makes explicit reference to the C standard and enforces compatibility with it. – Jens Gustedt Dec 13 '12 at 12:57
  • @JensGustedt Yes, but since the C standard uses the _t naming convention, it has become a very common one in C applications. Trying to ban 40 years of C code naming conventions is not particularly bright. – Lundin Dec 13 '12 at 13:02
  • @Lundin You're saying that nameless struct is sufficient, except when dealing with self-referential structs (hardly "odd" - used in linked lists, for example), which is what I said in the first place, but phrased to sound like a disagreement. – user4815162342 Dec 13 '12 at 13:03
  • So, this solve the problem? `typedef struct Function{ // Inputs int codeGenerationIterator; int i; char* s; // Outputs // Internal };` – Tommaso DS Dec 13 '12 at 13:15
  • Ok, finally, I've found a real C compiler (DEV-C++ with C option for compiler) and I've solved with `typedef struct Function Function; struct Function{ // Inputs int codeGenerationIterator; int i; char* s; // Outputs // Internal };`. Thanks to all! – Tommaso DS Dec 13 '12 at 13:52
3

Some example of compilers are: "Miracle C", "Tiny C" and the error does not provide any information

Maybe try a real compiler then? How about just take your code and throw it in GCC to get better error messages.

Despite that fact, it sounds like you are getting error messages: "missing ';' at Probably just means something to the compiler looks like it should have been two statements and you forgot to break it up with a ;, it might not be the best error message, but no compiler can always tell you outright what's wrong, they're just hints becuase they expect you to be smarter. :)

You have a bunch of structs in your code:

typedef struct Cerchio {
typedef struct Punto {
struct Function{

One of these structs is not like the others.

  • If you use the typedef you can refer to the structure just by the name Cerchio (for example).
  • If you do not use typedef you need to explicitly call it everytime: struct Function
Mike
  • 47,263
  • 29
  • 113
  • 177
1

In addition to the missing struct keywords, your code must #include <stdio.h>. In C99 this is required in order to be a well-formed program. In C89 the program is well-formed without it (once the other errors are fixed) but has undefined behavior.

gcc -pedantic-errors -std=c99 will give you the exact line numbers that contain errors, and in addition gives some warnings that you should pay attention to. Your definitions like:

typedef struct Punto { ... };

are all wrong even though they're legal. The typedef has no effect since you don't provide a name for the type you're supposedly def-ing. So the only way to identify it in C is as struct Punto, not Punto as you'd like and as it can be identified in C++.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699