Question

I tried to compile the following code, but the compiler wouldn't doing because " * is illegal for a struct" is that true?

struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
} String;

void main(){

    char *s;
    String *new_string = malloc(sizeof(String) + 10 + 1);

}
Was it helpful?

Solution

Either use a typedef:

typedef struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
} String;    /* now String is a type */

Or explictly say struct String:

void main(){
    char *s;
    struct String *new_string = malloc(sizeof(struct String) + 10 + 1);
}

OTHER TIPS

As nobody seems to have mentioned this yet, let me explain what the code you used actually means.

What you used is a kind of shorthand notation that defines a struct and also creates a variable. It is equivalent to:

struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
};
struct String String; //creates a global variable of type "struct String"

Later,

String *new_string

fails to compile because there is no type name by the name of "String" (only of "struct String". There is a global variable whose name is "String" but that doesn't make sense in this expression.

You forgot the typedef:

typedef struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
} String;
/* String is now a type, not an object */

void main(){

    char *s;
    String *new_string = malloc(sizeof(String) + 10 + 1);
}

Yes, it is true. Binary * operator (multiplication) is only applicable to arithmetic types. In your example you declared a variable Struct of type struct Struct and then tried to multiply it by something. This just doesn't make any sense. You can't multiply struct objects. This is what the compiler is telling you.

Additionally: 1. That's int main, not void main. 2. C language doesn't support array declarations with size 0. You might want to change the array declaration inside your struct type.

use this code:

struct String* new_string = malloc(sizeof(String)+10+1);

you can also consider typedef

typedef struct String sString;

will let you use your snippet:

sString* mystring

Try:

 typedef struct String_t {
        int length;
        int capacity;
        unsigned check;
        char ptr[0];
    } String;

Yours doesn't quite declare a type like that. More specifically, it hides your type by introducing a variable of the same name. And that gets the compiler confused... :)

Edit: I now see that the original question was tagged C and not C++ and someone erroneously tagged it C++ (reverted the tagging).


One solution, as others mentioned, is to add a typedef before the struct declaration however since this is C++ (according to the question's tag) and not C a more idiomatic and shorter way would be to just drop the trailing "String"

struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
};

This is enough to introduce a type called String the reason your original code didn't work was that in addition to introducing a type called String you introduced a variable called String which hid the type.

As artelius wrote earlier, your struct definition is likely not what you want. The easiest fix would be:

#include <stdlib.h>

struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
};

int main(){
    char *s;
    String *new_string = (String*)malloc(sizeof(String) + 10 + 1);
    return 0;
}

This actually compiles too when I tested with both gcc and g++. If you are really doing C++ as your tags imply, you should rather include cstdlib instead of stdlib.h or do it properly(tm) and turn your string into a class and use new.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top