I have the following code written in C:
n. struct UDSData {
char *name;
char *address;
};
n. char UDS1[16] = "fill up sixteen", UDS2[16] = "fill up sixteen";
n. while (something) {
...
108. char UDS1Temp[16], UDS2Temp[16];
109. strcpy(UDS1Temp, UDS1);
110. strcpy(UDS2Temp, UDS2);
111.
112. struct UDSData item = {UDS1Temp, UDS2Temp};
113. UDSCodes[UDSTotal++] = item;
}
Any idea why the code compiles to give these errors:
1><file>(112): error C2143: syntax error : missing ';' before 'type'
1><file>(113): error C2065: 'item' : undeclared identifier
1><file(113): error C2440: '=' : cannot convert from 'int' to 'UDSData'
Removing the strcpy() and inputting UDS1 and UDS2 directly into the struct works.
You are almost certainly using an early compiler standard, like C89, which does not allow mixed declarations and code. You need to declare item near the start of the code block. Something like this:
char UDS1Temp[16], UDS2Temp[16];
struct UDSData item = {UDS1Temp, UDS2Temp};
strcpy(UDS1Temp, UDS1);
strcpy(UDS2Temp, UDS2);
UDSCodes[UDSTotal++] = item
Since you are only placing the pointers into the struct, the initialisation can be done before the strcpy. But you must declare UDSData after the two char arrays.
Related
I'm trying to give a structure to a C function in Simulink. My steps so far:
Included the .h & .c in configuration parameters custom code. My header has a structure defind:
typedef struct mystruct
{ int m;
int *i;
double *x;}mystruct
Now in my MATLAB function under Simulink:
function y = fcn(u)%#codegen
m=int32(1);
i=zeros(10,1,'int32');
x=zeros(10,1);
s.m=m;
s.i=i;
s.x=x;
coder.cstructname(s,'mystruct','extern');
D=int32(0);
D=coder.ceval('accesmystruct',coder.ref(s));
y=10;
If I run the code I get a long error from the code generation that indicates that it can't be compiled in c-code. The error is:
c2_Test2.c
c2_Test2.c(57) : error C2143: syntax error : missing ')' before '*'
c2_Test2.c(57) : error C2081: 'cs_size' : name in formal parameter list illegal
c2_Test2.c(57) : error C2143: syntax error : missing '{' before '*'
c2_Test2.c(57) : error C2059: syntax error : ')'
c2_Test2.c(60) : error C2143: syntax error : missing ')' before '*'
....
This only happens if I declare the two variables i and x as Pointers. If I declare them as scalar in the header and MATLAB function it works.
Does any one see what I'm doing wrong?
Getting the Code to Compile
To get the code to compile I added:
#include "mystruct.h"
in the Simulation Target->Custom Code->Header File section. Adding the required include paths on that pane may be necessary as well.
Compatibility Concerns
After doing the above, the code crashes when running. The issue is that the definition of mystruct is not what MATLAB Coder is expecting.
When you define a MATLAB structure with fixed-size arrays inside of it, the type generated by MATLAB Coder uses static arrays inside of the C struct like:
typedef struct {
int32_T m;
int32_T i[10];
real_T x[10];
} mystruct;
You can see this in the code in the slprj directory if you remove the 'extern' from the coder.cstructname call.
A struct with inline arrays already has memory allocated for the arrays by the C compiler. However, when the fields are pointers, someone needs to allocate the space for the data, which has not been done here.
I see a few options:
Omit the 'extern' and allow MATLAB Coder/Simulink to generate the type definition
Declare your external structure with arrays rather than pointers for i and x
Before writing to or reading from the struct, pass it to another C function that allocates memory for the fields:
function y = fcn(u)
%#codegen
m=int32(1);
i=zeros(10,1,'int32');
x=zeros(10,1);
s = coder.nullcopy(struct('m',m,'i',i,'x',x));
coder.cstructname(s,'mystruct');
coder.ceval('initmystruct',coder.wref(s),int32(numel(i)),int32(numel(x)));
s.m=m;
s.i=i;
s.x=x;
And in C:
/* Example of initmystruct with no error checking */
/* int is the size type assuming it matches int32 */
/* in the MATLAB coder.ceval call */
void initmystruct (mystruct *s, int szi, int szx)
{
s->i = malloc(szi*sizeof(*s->i));
s->x = malloc(szx*sizeof(*s->x));
}
According to the doc for cstructname the header file needs to be specified using the 'Headerfile' input argument.
I get the error 'J_TypeInstructions' redeclared as different kind of symbol' in the following C code:
struct _J_TypeInstructions {
const char *instructionName;
} J_TypeInstructions[] = { { "j", "000010" } };
//typedef struct _J_TypeInstructions J_TypeInstructions;
Try with that instead:
struct _J_TypeInstructions {
const char *instructionName;
} J_TypeInstructions[] = { {"j"}, {"000010"} };
/* ^ ^ */
and do not use a tag name like _J_TypeInstructions as identifiers beginning with _[A-Z]* are reserved in C.
EDIT: I missed the commented line was a part of the question:
typedef struct _J_TypeInstructions J_TypeInstructions;
You already declared a variable with the identifier J_TypeInstructions. You cannot declare a type with the same name of a variable in the same scope as identifiers for variables and type names live in the same name space. Change the name of your variable to fix the issue.
J_TypeInstructions can't be both variable name and type.
First, you created a variable(an array of _J_TypeInstructions structures) called J_TypeInstructions
then you try to define type with the same name as previously defined array.
Also, as ouah mentioned in his answer, fix your braces because the way you use them now is try to initialize one char * with 2 values and that's definetelly giving you a warning.
I'm currently learning C. I've been playing around with typedef and structs, and ran into a strange error (at least to my inexperienced eyes).
I am using a typedef to create a dimensions type (int array of two values), and I have a struct that uses that type def.
Upon trying to specify values for the field in my main, I run into an error:
error: expected expression before ‘{’ token
The code:
typedef int dimensions[2];
struct television
{
dimensions resolution;
};
int main()
{
struct television theTV;
theTV.resolution = {1024, 768};
return 0;
}
It's a very contrived example -- is it possible to initialise the .resolution variable in this way?
Use instead:
struct television theTV = {{1024, 768}};
{} initializer list can only be use in a declaration and cannot be used in a statement.
You are not allowed to use assignment to an array, since it is a non-modifiable l-value. However, you can use memcpy() with a compound literal:
memcpy(theTV.resolution, (dimensions){1024, 768}, sizeof(dimensions));
I'm trying to add a struct to my program using this syntax:
struct foo {
char bar[] = "baz";
char qux[] = "abc";
/* and so on */
};
For some reason, I get an error on each variable declaration within the struct saying that I have to add semicolons, and seems to fall into a kind of loop with this. The suggested syntax would be something like
struct foo {
char bar[]; =; ;;;;;;/* infinite semicolons */"baz";
}
This is the first time I've had this kind of error; am I really doing something wrong, or is this just an issue with the compiler itself?
This has nothing to do with Xcode. At all.
You're getting a compiler error because you can't initialize structs like this.
The struct type definition is about types only. Assigning values to members at this point makes no sense. Maybe you meant
struct foo {
char *bar;
char *baz;
};
struct foo x = { "quirk", "foobar" };
instead?
You are doing something wrong. You cannot assign values to the members of the struct… you're in the middle of defining the data type, not an instance of it.
This will give you your struct definition and then directly declare a variable (with initialization) of its type:
struct foo {
char *bar;
char *qux;
} variable_name = {
"baz", "abc"
};
I know this is a very basic problem, but I cannot move forward without it and its not clearly explained elsewhere.
Why is this programming giving me so many errors of undeclared identifier? I have declared it, though.
These are the error i am getting.
Error 2 error C2143: syntax error : missing ';' before 'type'
Error 3 error C2065: 'ptr' : undeclared identifier
Error 4 error C2065: 'contactInfo' : undeclared identifier
Error 5 error C2059: syntax error : ')'
Error 15 error C2223: left of '->number' must point to struct/union
and more...
#include<stdio.h>
#include<stdlib.h>
typedef struct contactInfo
{
int number;
char id;
}ContactInfo;
void main()
{
char ch;
printf("Do you want to dynamically etc");
scanf("%c",&ch);
fflush(stdin);
struct contactInfo nom,*ptr;
ptr=(contactInfo*)malloc(2*sizeof(contactInfo));
nom.id='c';
nom.number=12;
ptr->id=nom.id;
ptr->number=nom.number;
printf("Number -> %d\n ID -> %c\n",ptr->number,ptr->id);
}
typedef struct contactInfo
{
int number;
char id;
}ContactInfo;
This code defines 2 things:
a type named ContactInfo
a struct named contactInfo
Notice the difference of the c and C!
In your code you are using a mixed combination of both, which is allowed (although confusing IMHO).
If you use the struct variant you need to explicitly use struct contactInfo. For the other variant (ContactInfo) you must to omit the struct part as it is part of the type definition alteady.
So be careful with both different definitions of your structure. Best would be to only use either one of the variants.
I do not have Visual Studio at hand, but the following (corrected) code compiles with gcc properly without any warnings:
#include<stdlib.h>
typedef struct contactInfo
{
int number;
char id;
}ContactInfo;
void main()
{
ContactInfo nom,*ptr;
ptr=malloc(2*sizeof(ContactInfo));
}
(I left out the not so interesting/unmodified parts of the code)
This:
ptr=(contactInfo*)malloc(2*sizeof(contactInfo));
is wrong, there's no type called contactInfo.
There's a struct contactInfo, which is typedef:d as ContactInfo. C is case-sensitive (and you must include the struct unlike how it works in C++).
Also note that the quoted line is better written as:
ptr = malloc(2 * sizeof *ptr);
Since casting the return value of malloc() is a bad idea in C, I removed the cast. Also, repeating the type is a bad idea since it makes the risk of introducing error greater, so I removed that as well.
Note that sizeof *ptr means "the size of the the type that ptr points at" and is a very handy thing.
C is a case sensitive language.
ptr=(contactInfo)malloc(2*sizeof(contactInfo));
which should be:
ptr=malloc(2*sizeof(ContactInfo));
Replace
ptr=(contactInfo*)malloc(2*sizeof(contactInfo));
with
ptr=malloc(2*sizeof(struct contactInfo));
struct contactInfo nom,*ptr;
ptr=(contactInfo*)malloc(2*sizeof(contactInfo));
here you are using contactInfo to typcast where as it should be struct contactInfo. and as you have typedef it into ContactInfo you can use that also.
struct contactInfo nom,*ptr;
ptr=(ContactInfo*)malloc(2*sizeof(ContactInfo));