how to use struct in gcc? - c

I am of late working on gcc compiler. whenevr i m compiling my code, m encountering problem with declaration of structure. How to tackle this problem. Do i need to write the syntax differently in gcc?. if yes, how? please suggest something.

I am reasonably sure gcc conforms to C standards, for a more succinct explanation than one found in the standard, please, turn to pages 148-150 of C: A Reference Manual.
So something simple like this linked list element:
struct foo
{
int a;
float b;
char *s;
struct foo *next;
} my_struct;
should work.
If your needs are more complex.. then you should post your non-working example.
EDIT: If you don't have access to CAR then this will suffice for now: http://publications.gbdirect.co.uk/c_book/chapter6/structures.html (obviously not C99)

Related

gcc struggling with struct foo_v1 : foo_v2 { a; };

my gcc (9.1.0) struggle with following structure definition
struct foo_v1 : foo_v2 { a; };
i guess it could be a matter of coding version such as ansi or c99.
reading 9.4.0 i could not find <struct a : b { c; };> notation.
please could anyone give me a hint where to find standard defining such a notation or how to compile with gcc.
have a great day
how to compile with gcc.
It is not valid C syntax. It is not possible to compile it with gcc as a C source code. It is also not a common extension in common C compilers.
It may be possible to compile the following with a C++ compiler (which makes the line compile-able after adding two lines and adding -xc++ to gcc):
struct foo_v2 { int stuff; };
#define a int variable
struct foo_v1 : foo_v2 { a; };
The presented line in the question, on its own, is not valid C++ code anyway.

Macro for struct members

I have a struct definition that I am not allowed to change. However, I would like to access a member after doing an operation on it (the operator appears after the first operand). It occurred to me that I could use a macro to access the modified value as if it were part of the struct itself.
struct test{
int a;
int b;
} *t;
#define c b+1
...
printf("%d", t -> c);
This does look nicer to me, but it feels like something could go wrong with replacement. Is there a better way to do something like this? Is this bad practice? What can go wrong?
What can go wrong?
printf("%d", t->c * 3);
For starters.
Your suggestion is bad.
Single letter members and macros (but let's ignore that)
Hard to read and support. (is t->c a member or one of those crazy marcros I added? Was c +1 or -1?
If you really have to macro-ize it for some reason, then make it clearer.
e.g.
#define BPlusOne(t) ((t)->b + 1)
printf("%d", BPlusOne(t));
If it's just a simple piece of work for school this is overkill, but I'm currently working on a big system where the structs are generated as are all of these type of macros, and in this case it works (but I still wouldn'thave done it this way ;-)

Is message "the ABI of passing struct with a flexible array member has changed in GCC 4.4" important?

I am wondering if this message from the compiler is something that one should carefully consider.
Let's look at the following code:
struct s
{
int a;
int b[];
};
void fun(struct s c)
{
}
int main()
{
return 0;
}
which gives the following error:
main.c:7:6: note: the ABI of passing struct with a flexible array member has changed in GCC 4.4
My question is: is using such structure in bigger projects safe? What are the possible risks and effects of such structure (besides the compiler message)?
With respect to memory every time we are calling this function the structure variable is created so wastage of memory.
confirm whether u need struct s c or struct s &c in your project.

Why GCC compiles this erroneous code?

I tried to compile something like:
struct A
{ int a;
struct B
{ int c;
};
};
Now when I compile this code the compiler gives me a warning message that:
declaration does not declare anything [enabled by default]
I know that I have not defined any instance of struct B. That will mean that I shall not be able to access variable c. Still compiler compiles this code with a warning. What's the whole point ? Why does not the compiler give a compilation error instead ?
ADDED Info:
The size of the struct A is equal to the size of int on my machine!!
Because you can do this:
struct A
{ int a;
struct B
{ int c;
};
};
int main()
{
struct A a = {1};
struct B b = {2};
return a.a + b.c;
}
Note:
you need a semicolon after declaring B, which your code is missing
this isn't particularly useful, but I suppose it might serve some documentary purpose (ie,to suggest a relationship or grouping between types)
in C++, the second variable would have type A::B, but C doesn't have the same scoping rules (all structs just belong to the global struct namespace, in effect)
As to the motivation for allowing it ...
struct Outer {
struct {
int b;
} anon;
/* this ^ anonymous struct can only be declared inside Outer,
because there's no type name to declare anon with */
struct Inner {
int c;
} named;
/* this ^ struct could be declared outside, but why force it to be
different than the anonymous one? */
struct Related {
double d;
};
/* oh no we have no member declared immediately ... should we force this
declaration to be outside Outer now? */
struct Inner * (*function_pointer)(struct Related *);
/* no member but we are using it, now can it come back inside? */
struct Related excuse;
/* how about now? */
};
Once you've allowed nested type declarations like this, I doubt there's any particular motivation to require there be a member of that type right away.
It's legal (but extremely bad style) to do:
struct A {
int a;
struct B {
int c;
};
};
struct B B_instance;
struct A A_instance;
And the compiler doesn't know about the later variables that use the struct types, so it really should not error out.
Generally, a warning means the code likely does not do what you intended but is legal in the language. The compiler is saying, “This is likely not what you really wanted to do, but I must allow you to do it because the language says it is allowed.” The compiler cannot give you an error for this code because the C standard permits it, so it must be allowed (unless you specifically ask for errors for such things, as by using GCC’s -Werror option to turn warnings into errors).
The C standard does not attempt to define everything that makes sense in a program. For example, these things are legal in C:
3;
if (x) then foo(); else foo();
x = 4*0;
The first statement has no side effects, and its return value is not used. But it is legal in C, since a statement may be just an expression. The second statement just calls foo(), so the if is pointless. In the third statement, multiplying by four is pointless.
It would be extremely difficult to write a C standard that prohibited all things that did not make sense. And it is certainly not worth the effort. So this is part of your answer: When the committee writing the C standard builds the language, do they want to spend a lot of time rewriting the technical specification to exclude things that do not make sense? Sometimes yes, if it seems valuable to avoid something that could cause serious bugs. But much of the time, it is just not worth their time and would complicate the specification unnecessarily.
However, compilers can recognize some of these things and warn you. This helps catch many typographical errors or other mistakes.
On the other hand, sometimes these constructions arise from unusual circumstances. For example, a program may have preprocessor statements that define struct A in different ways when building for different targets or different features. In some of those targets, it may be that the struct B member is not needed in struct A, so it is not declared, but the declaration of struct B (the type, not the object) remains present just because it was easier to write the preprocessor statements that way.
So the compiler needs to permit these things, to avoid interfering with programmers writing a wide variety of programs.
You are, in fact, declaring struct B here, but you are not declaring a variable of that type.
This is a warning, but one you should fix. Perhaps you meant:
struct A
{ int a;
struct B
{
int c;
} c;
};

How to check for unused members in struct?

If I declare and never use variable then gcc will give me a warning.
But if I have a struct with several members and some of those are not used, gcc will not warn about it...
Is there an option (or another method) to check these?
(Of course I can manually delete some entries and try to compile again, but I am looking for this kind of approach).
Thanks
No GCC won't warn about this. Mostly because in the majority case whether or not a member is used can't be determined. A good portion of struct are defined in a header file. This can be used by not just your application but by any other application referencing your .lib or using the same header file. Hence just because the current piece of code being compiled doesn't use the member it doesn't mean that the member is not used by some other piece of code.
Local variables are different. Whether or not they are used easily determined by compiling only the function in question. Hence GCC, and many other compilers, give a warning.
You can legally and portably access the first member of a struct without using its name, simply by casting the struct to the type of the first member.
typedef struct {
int x;
} mystruct;
mystruct s;
*(int*)&s = 3;
You can also non-portably, but with virtually 100% reliability, access any field in the struct without using its name by casting the struct to another struct type with a compatible structure.
typedef struct {
int x;
char y;
} mystruct;
typedef struct {
int a;
char b;
} otherstruct;
mystruct s;
((otherstruct*)&s)->b = 'C';
I'm afraid that this means that neither searching the source for the field's name, nor removing it, are completely reliable.

Resources