Simple program won't compile in C - c

Okay I know right off the bat this is going to be a stupid question, but I am not seeing why this simple C program is not compiling.
#include <stdio.h>
#include <stdlib.h>
typdef struct CELL *LIST;
struct CELL {
int element;
LIST next;
};
main() {
struct CELL *value;
printf("Hello, World!");
}
I am new to C programming, not to programming in general, but to C. I am familiar with Objective-C, Java, Matlab, and a few others, but for some reason I can not figure this one out. I am trying to compile it using GCC in OS X if that makes a difference. Thanks for your help!
The error message I am getting is
functionTest.c:5: error: expected specifier-qualifier-list before ‘LIST’
functionTest.c:7: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘struct’

Most importantly: You have misspelled typedef.
Then, at least these days, we normally add a return type to main, like so:
int main()
Also, main is supposed to return the exit status, so:
#include <stdio.h>
#include <stdlib.h>
typedef struct CELL *LIST;
struct CELL {
int element;
LIST next;
};
int main() {
struct CELL *value;
printf("Hello, World!\n");
return 0;
}

The main reason is that you typoed typedef as typdef. However, there are a couple other things you should do:
Add return 0; to the end of main().
Change the signature of main to int main(void)

Did you try to compile it with gcc -Wall -g yourprog.c -o yourbinary ?
I'm getting:
yourprog.c:3:8: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'struct'
yourprog.c:6:5: error: unknown type name 'LIST'
yourprog.c:8:1: warning: return type defaults to 'int' [-Wreturn-type]
yourprog.c: In function 'main':
yourprog.c:9:18: warning: unused variable 'value' [-Wunused-variable]
yourprog.c:11:1: warning: control reaches end of non-void function [-Wreturn-type]
and you mispelled typedef and you should change the signature of main and add a return 0; inside.
By the way, I find your typedef very poor taste. I suggest to code (like Gtk does) something like typedef struct CELL CELL_t and declare CELL_t* value = NULL. because you really want to remember that value is a pointer to CELL_t. In particular, I hate typedef-s like typedef struct CELL* CELL_ptr; because I find very imporrtant (for readability reasons) to quickly understand what is a pointer and what is not a pointer.
Actually I would rather suggest
struct cell_st;
typedef struct cell_st cell_t;
cell_t *value = NULL;
(I do like initializing all pointers to NULL).

Add a return in your main function

Related

Passing struct to a function to assign values

I am trying to pass a struct to a function residing in a separate file. When passing the struct as an argument, it throws errors.
Test.c
struct student{
int rollNumber;
unsigned char name[20];
int marks;
};
void func(struct student devanshu);
int main(){
struct student devanshu;
func(&devanshu);
printf("--------------------%d\n", devanshu.rollNumber);
printf("--------------------%d\n", devanshu.marks);
printf("--------------------%s\n", devanshu.name);
}
NewTest.c:
void func(struct student devanshu)
{
devanshu.rollNumber = 1;
devanshu.marks = 909;
strcpy(devanshu.name, "abc.xyz");
return;
}
And this is the output that I get:
In file included from test.c:6:0:
newtest.c:10:30: error: parameter 1 (‘devanshu’) has incomplete type
void func(struct student devanshu)
test.c: In function ‘main’:
test.c:23:7: error: incompatible type for argument 1 of ‘func’
func(&devanshu);
^
In file included from test.c:6:0:
newtest.c:10:6: note: expected ‘struct student’ but argument is of type ‘struct student *’
void func(struct student devanshu)
newtest.c:10:30: error: parameter 1 (‘devanshu’) has incomplete type
void func(struct student devanshu)
newtest.c:7:20: error: storage size of ‘devanshu’ isn’t known
struct student devanshu;
If I use the function in the same file i.e in test.c it does not throw any error and works just fine. But when keeping the functions in two different files, it gives me these errors.
Would be thankful if somebody could help me get through. Thanks in advance.
error: parameter 1 (‘devanshu’) has incomplete type
This means that the struct definition isn't visible to the file you use it inside. Unless this is intentional, you need to place the struct definition in a header file and include that by every .c file using the struct.
expected ‘struct student’ but argument is of type ‘struct student *’
You have written the functions incorrectly. It should be void func(struct student* devanshu); and inside the function you should access members with devanshu-> .... Otherwise you just pass a copy of the struct to the function and then change the local copy.
The errors are pretty self explanatory. Take this one:
test.c: In function ‘main’:
test.c:23:7: error: incompatible type for argument 1 of ‘func’
func(&devanshu);
It means you're passing something to func that has a different type to what you've told the compiler that func accepts. You've declared the function to take a struct student
void func(struct student devanshu);
but the function call is passing a pointer to struct student.
func(&devanshu);
The function call is correct as you want the function to have access to the struct you're passing and not a copy. So you'll need to change the function to take a struct student *.
The other errors are because you're not using an include file to store the definition of the struct.
Create a file called "student.h" (or whatever) and move the definition of the struct into it. And also the declaration of the function too.
struct student{
int rollNumber;
unsigned char name[20];
int marks;
};
void func(struct student *);
and at the top of both C files you put
#include "student.h"
which tells the compiler to copy the contents of that file into your C files when you're compiling. It means you have a consistent definition that can be shared by all the files that need it.
Ok, this will work: (Explanation below)
test.h: (New file!)
struct student{
int rollNumber;
char name[20];
int marks;
};
test.c:
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
void func(struct student *devanshu);
int main(){
struct student devanshu;
func(&devanshu);
printf("--------------------%d\n", devanshu.rollNumber);
printf("--------------------%d\n", devanshu.marks);
printf("--------------------%s\n", devanshu.name);
}
NewTest.c:
#include <string.h>
#include "test.h"
void func(struct student *devanshu)
{
devanshu->rollNumber = 1;
devanshu->marks = 909;
strcpy(devanshu->name, "abc.xyz");
return;
}
This
unsigned char name[20];
will give you problems later on strcpy(). Change to just char.
This
void func(struct student devanshu);
is not wrong, but you fall into a trap. Structures in C are always passed by value (copy) of the entire struct. So, if you want func() to modify the original struct, you have to explicitly tell it so:
void func(struct student *devanshu);
Then, in func, you need to change the access syntax to using the -> operater insteadf of '.'
As you are using the struct student in both files, you need to move the declaration of the struct out into a header file. You could (as I did on the very first edit) also repeat the declaration because I was lazy, but the comments are 100% right: That is a very dangerous practice, so I changed that.

error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token in struct

I'm getting the error when compiling with gcc -Wall -std=c99:
pokerhand.c:20:17: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
Card *cards = malloc(sizeof(Card)*5);
here is my code where the error is happening
typedef struct card
{
char suit;
char *face;
} Card;
typedef struct hand
{
Card *cards = malloc(sizeof(Card)*5);
char *result;
} Hand;
all I have before these structs is header includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
You can't write code inside a struct declaration. That is wrong.
I bet this would solve the error
typedef struct hand
{
Card *cards;
char *result;
} Hand;
And later you can allocate to it when you have proper variable declared with that type.
Also this would work
typedef struct hand
{
Card cards[5];
char *result;
} Hand;
If you think that each hand would contain 5 card every single time then yes you can add it like this.
In the first case you need to allocate the cards and then free it when you are done working with it.
You can't "do things" with the struct members when you define the struct.
So Card *cards = malloc(sizeof(Card)*5); makes no sense, and the compiler issues a diagnostic.
One solution is to build an init_card function, that takes a struct card* as an input parameter; and you perform your initialisation there. If you also build a corresponding free_card function you'll end up with something that scales up remarkably well.

C Structures: Printing a string member produces weird results

I am independently learning C. I have a four member struct as follows:
#define aSize 10
struct Students {
char lastName[aSize];
char firstName[aSize];
int age;
int grade;
}
I have two separate functions (in the main.c file):
void pasteInfo_1(struct Students S1) {}
and
void printStudents(struct Students S1) {}
pasteInfo() uses strcpy() and assignment to assign values to the members; printStudents() then prints the values stored in the members. When I compile the file:
#in makefile
CFLAGS = -lm -o -Wall
gcc main.c $(CFLAGS) main
It compiles with no errors. However, when I call the executable it prints some very weird characters that look like binary/assembly. Any suggestions? Here are the individual functions.
void pasteInfo_1(struct Students S1) {
strcpy(S1.lastName, "Effinger");
}
And here is printStudents:
void printStudents(struct Students S1) {
printf("%s\n",S1.lastName);
}
The function calls in main:
int main() {
struct Students S1;
pasteInfo_1(S1);
printStudents(S1);
}
Re: Modifications.
After adding the changes suggested by user3629249, I got the following errors:
main.c:6:23: warning: ‘struct Students’ declared inside parameter list will not be visible outside of this definition or declaration
void pasteInfo(struct Students * pS1);
^~~~~~~~
main.c:7:27: warning: ‘struct Studens’ declared inside parameter list will not be visible outside of this definition or declaration
void printStudents(struct Studens S1);
^~~~~~~
main.c: In function ‘main’:
main.c:22:14: warning: passing argument 1 of ‘pasteInfo’ from incompatible pointer type [-Wincompatible-pointer-types]
pasteInfo( &S1);
^
main.c:6:6: note: expected ‘struct Students *’ but argument is of type ‘struct Students *’
void pasteInfo(struct Students * pS1);
^~~~~~~~~
main.c:23:17: error: type of formal parameter 1 is incomplete
printStudents(S1);
^~
main.c: At top level:
main.c:26:6: error: conflicting types for ‘pasteInfo’
void pasteInfo(struct Students * pS1)
^~~~~~~~~
main.c:6:6: note: previous declaration of ‘pasteInfo’ was here
void pasteInfo(struct Students * pS1);
^~~~~~~~~
main.c:32:6: error: conflicting types for ‘printStudents’
void printStudents(struct Students S1)
^~~~~~~~~~~~~
main.c:7:6: note: previous declaration of ‘printStudents’ was here
void printStudents(struct Studens S1);
^~~~~~~~~~~~~
It seems from your error messages as though you need to forward declare struct Students and/or pasteInfo. See your textbook for advice on how to do that, if necessary.
I am independently learning C.
What does this mean? Are you reading from a book? If so, which book?
Keep in mind that it's dangerous to learn C by misguided trial and error; what you'll most likely end up learning is something that differs from C in subtle and possibly dangerous ways, and which medications best deal with the headaches you give yourself...
That's the peril of learning by misguided trial and error; you'll run into a lot of undefined behaviour (and implementation-defined behaviour) that will differ from system to system and might not make sense at the time...
You're better off avoiding UB and IB by reading a decent book such as K&R2E, and doing the exercises as you stumble across them.
when the called function plans to (directly) change anything in the caller function, pass the address of the item to the called function. I.E.
int main( void )
{
struct Students S1;
pasteInfo_1( &S1 ); // <-- passing pointer to struct
printStudents( S1 );
}
Then modify the pasteInfo_1()` function to expect a pointer,
void pasteInfo_1( struct Students * pS1 )
{
strcpy( pS1->lastName, "Effinger" );
}
Note the use of vertical alignment of the braces and the use of appropriate horizontal spacing.
The purpose of the vertical alignment and horizontal spacing is to make the code much more readable.
Solved it! Here is the working code:
(Special Thanks to user3629249 and Seb for their advice)
'#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
struct Students
{
char lastName[8];
char firstName[6];
int age;
int grade;
};
void pasteInfo(struct Students *S1);
void printStudnets(struct Students S1);
int main(void)
{
struct Students S1;
pasteInfo( &S1 );
printStudents( S1 );
}
void pasteInfo(struct Students *S1)
{
strcpy(S1->lastName, "Effinger");
}
void printStudent(struct Students S1)
{
printf("%s\n",S1.lastName);
}

C struct declaration and initialization

I have been following tutorials from the web on creating a struct and then initializing it in main(). From the tutorials I have followed, I have created my own example, which is as follows:
#include <stdio.h>
struct test {
int num;
};
main() {
test structure;
}
However, this does not work:
test.c: In function 'main':
test.c:8: error: 'test' undeclared (first use in this function)
test.c:8: error: (Each undeclared identifier is reported only once
test.c:8: error: for each function it appears in.)
test.c:8: error: expected ';' before 'structure'
But when I change:
test structure;
to:
struct test structure;
the code compiles. Why is this though? From the numerous examples I have looked at it seems that I shouldn't need the 'struct' before 'test structure'.
Thanks for your help/comments/answers.
You were reading C++ examples. In C the type of your structure is struct test not test.
You can get around that by doing
typedef struct test_s
{
int num;
} test;

errors while trying to pass a structure to a function

In the following program I try to pass a structure to a function. But I get errors,and I do not understand why. What mistake have I made in this program ?
I am using gcc for compiling this c program.
#include <stdio.h>
struct tester {
int x;
int *ptr;
};
void function(tester t);
int main() {
tester t;
t.x = 10;
t.ptr = & t.x;
function(t);
}
void function(tester t) {
printf("%d\n%p\n",t.x,t.ptr);
}
Errors :
gcc tester.c -o tester
tester.c:8:15: error: unknown type name ‘tester’
tester.c: In function ‘main’:
tester.c:12:2: error: unknown type name ‘tester’
tester.c:13:3: error: request for member ‘x’ in something not a structure or union
tester.c:14:3: error: request for member ‘ptr’ in something not a structure or union
tester.c:14:13: error: request for member ‘x’ in something not a structure or union
tester.c: At top level:
tester.c:18:15: error: unknown type name ‘tester’
NOTE : If I replace printf with cout and stdio with iostream and name the extension to .cpp (!), I get no errors. Why is that ? No wonder I compile it using g++
If you don't typedef the struct you must specify struct in front of the struct name while declaring it like so:
struct tester t;
Either you do that or you do the following:
typedef struct {
int x;
int *ptr;
}tester;
Update
Below is a quote from Adam Rosenfield from the following post Difference between 'struct' and 'typedef struct' in C++?:
In C++, all struct/union/enum/class declarations act like they are implicitly typedef'ed, as long as the name is not hidden by another declaration with the same name.
your struct isn't named. either use struct tester t; or usa a typedef
The thing is you're trying to compile with gcc, which is a "c language" compiler and you're following C++ style of code.
It is possible to create a struct variable by just structname variablename;
but in c++, you explicitly have to tell the compiler it is a struct like
struct structname variablename;
Just do that and you'll be fine, otherwise you can use a typedef which is basically you tell the compiler form now on you are going to call struct tester to only tester, which will suit you more since you only have to only a minor change.

Resources