Directing pointer to struct causes expression syntax error - c

This maybe a completely obvious error but I can't figure out why my code below won't work. I'm rather unfamiliar with C, though I have made some programs using it.
I'm using Turbo C (v.3.2), so that might also be the issue; however, I'm not sure.
static struct sector
{
float floor, ceil;
vec2 *verts;
signed char *neighbors;
unsigned npoints;
}*sectors = NULL;
static unsigned NumSectors = 0;
static struct player
{
vec3 position, velocity;
float anlge, anglesin, anglecos, yaw;
unsigned sector;
}player;
void DrawScreen()
{
enum{ MaxQueue = 32 };
unsigned s = 0;
struct item { int sectorno,sx1, sx2; } queue[MaxQueue], *head=queue, *tail=queue;
int ytop[W]={0}, ybottom[W], *renderedsectors = (int*)malloc(NumSectors*sizeof(int));
for(s = 0; s < W; ++s) ybottom[s] = H-1;
for(s = 0; s < NumSectors; ++s) renderedsectors[s] = 0;
//This line causes an Expression syntax error.
//From my understanding the pointer is moved to this structure inside the array.
//Corrections welcome as I want to learn c more in order to
//use it in more projects of mine.
*head = (struct item) { player.sector, 0, W-1 };
if(++head == queue+MaxQueue) head = queue;
do{
const struct item now = *tail;
const struct sector* const sect = &sectors[now.sectorno];
if(++tail == queue+MaxQueue) tail = queue;
if(renderedsectors[now.sectorno] & 0x21) continue;
++renderedsectors[now.sectorno];
for(s = 0; s < sect->npoints; ++s)
{
}
}while(head != tail);
}
I'm aware of the age of Turbo C but I have to use it due to it running in DOSBox, where my final executable has to work.
I'm copying the code from this website and I'm pretty sure he used another compiler, which probably was also newer.
I didn't work a lot with C and I mostly either used C++ in my free time or C# on the job, but I need to use it now due to the restrictions I'm facing.

The line of code that is causing your error message (shown below) is using what is known as a compound literal. This allows an anonyomus object of the type specified in the parentheses to be constructed from the data provided in the initializer list (inside the braces).
*head = (struct item) { player.sector, 0, W-1 };
The problem you're facing is that this construct was only incorporated into the C language in the "C99" (formally, ISO/IEC 9899:1999) version of the Standard – which, as it's name implies, was published in 1999.
However, the compiler you are using (Turbo C, v3.2) was released in or around 1993, so it almost certainly does not support this feature. (Some pre-1999 compilers may have supported compound literals as extensions but I doubt that Turbo C was one of them.)
There are two things you can do to circumvent the error:
Use a more modern (i.e. less than 20 years old) compiler.
Create an explicit temporary structure and assign that to the *head target:
struct item temp = { player.sector, 0, W - 1 };
*head = temp;
Note that, in the second case, your temp variable will have the same scope (and lifetime) as the anonymous object created by the compound literal.

Related

Casting a void pointer (that is part of a struct) into another pointer data type

I'm trying to figure out how to parse S-expressions in C on my own, in order to store data and code for my own rudimentary Lisp (written as a learning exercise, not for production).
Before explaining my code and my reasoning, I should explain that all I know about S-expressions is the introductory section of the Wikipedia article on it, and the occasional glance at Common Lisp code, so the naming of my structs and variables may be a bit off.
My language of implementation is C, and before I defined any functions I created the following structs:
typedef enum {
string,
letter,
integer,
} atom_type;
typedef struct {
void* blob;
atom_type type;
} atom;
typedef struct expr {
atom* current;
struct expr* next;
} expr;
Each atom is stored in a struct atom, which contains a enum instance (? I'm not sure of the correct jargon for this) and a void pointer pointing to the data to be stored. Each S-expression "node" consists of a pointer to an atom and a pointer to the next S-expression node.
I've written a rudimentary function that accepts a string and parses it into an atom, like the following:
atom* parse_term(char* str) {
size_t len = strlen(str);
atom* current = malloc(sizeof(atom));
if(str[0] == '\'') {
current->blob = (char*) &str[1];
current->type = letter;
} else if(str[0] == '\"') {
char temp[256];
int pos = 1;
while(str[pos] != '\"') {
temp[pos] = str[pos];
pos++;
}
current->blob = malloc(256 * sizeof(char));
current->blob = (char*) &temp;
current->type = string;
} else if(isdigit(str[0])){
char temp[256];
int pos = 0;
while(str[pos] != ' ') {
temp[pos] = str[pos];
pos++;
}
int tmp = atoi(temp);
current->blob = (int*) &tmp;
current->type = integer;
}
return current;
}
The function seems to be working correctly; at least, when I print out the data type it shows it correctly. But apart from this I can't figure out how to print out the actual 'blob': I've tried using the %p formatting code, as well as a switch statement:
void print_atom(atom* current) {
switch(current->type) {
case string:
printf("atom%s\ttype:%d", current->blob, current->type);
case letter:
printf("atom%c\ttype:%d", current->blob, current->type);
case integer:
printf("atom%c\ttype:%d", current->blob, current->type);
}
}
But this doesn't work. In the case of a string, it returns garbled text and in the case of everything else, it just doesn't print anything where the atom's information is supposed to be.
I imagine this is a product of my use of a void* within a struct; how could I remedy this? I think I did cast properly (though I could very well be wrong, please tell me), the only other option I could concieve of is storing a hardcoded variable for every supported data type in the 'atom' struct, but this seems wasteful of resources.
Don't use void*. Use a union. That's what unions are for.
In this example, I use an "anonymous union", which means that I can just refer to its fields as though they were directly inside the Atom struct. (I changed the spelling of names according to my prejudices, so that types are Capitalised and constants are ALLCAPS. I also separated the typedef and struct declarations for Atom, in case Atom turns out to be self-referential.
typedef enum {
STRING,
LETTER,
INTEGER
} AtomType;
typedef struct Atom Atom;
struct Atom {
union {
char* str;
char let;
int num;
};
AtomType type;
};
void print_atom(Atom* current) {
switch(current->type) {
case STRING:
printf("atom %s\ttype:%d", current->str, current->type);
case LETTER:
printf("atom %c\ttype:%d", current->let, current->tyoe);
case INTEGER:
printf("atom %d\ttype:%d", current->num, current->type);
}
}
As someone says in a comment, that's not actually how Lisp objects look. The usual implementation is combine cons cells and atoms, something like this (instead of AtomType). You'll also need to add CELL to your enum.
typedef struct Cell Cell;
struct Cell {
union {
char* str;
char let;
int num;
struct {
Cell* hd; // Historic name: car
Cell* tl; // Historic name: cdr
};
};
CellType type;
};
Here there's an anonymous struct inside an anonymous union. Some people say this is confusing. Others (me, anyway) say it's less syntactic noise. Use your own judgement.
The use of Cell* inside the definition of Cell is the motivation for typedef struct Cell Cell.
You can play not-entirely-portable-but-usually-ok games to reduce the memory consumption of Cell, and most real implementations do. I didn't, because this is a learning experience.
Also note that real Lisps (and many toy ones) effectively avoid most parsing tasks; the language includes character macros which effectively do what parsing is needed (which isn't much); for the most part, they can be implemented in Lisp itself (although you need some way to bootstrap).

Equality of structure using pragma pack in C

The reason behind the fact that the structures can't be checked for equality in C is the presence of slack bytes,which makes the comparison impossible.
But if I use #pragma pack(1) which removes the slack bytes then the comparison should be done smoothly,but it still gives error on being compared.
Example Code
#include<stdio.h>
#pragma pack(1)
struct person
{
int uid;
char nameStart;
};
struct personDupe
{
int uid;
char nameStart;
};
int main()
{
struct person var;
struct personDupe varDupe;
printf("\nSize of person : %3d\n",sizeof(var));
printf("\nSize of personDupe : %3d\n",sizeof(varDupe));
var.uid = 12;
var.nameStart = 'a';
varDupe.uid = 12;
varDupe.nameStart = 'a';
if(var == varDupe) //Error is introduced
printf("\nStructures are equal\n");
return 0;
}
Your code doesn't compile since you can't compare directly two struct.
You should use something like memcmp:
memcmp(&var, &varDupe, sizeof(var));
This doesn't solve the padding problem, which can be solved by ensuring that a struct is properly initialized to a known value even on padding bytes (which can be obtained by memset prior to initialization of fields).
But the approach of packing a struct to remove padding just to check if they are equal seems a fragile solution. If the compiler wants padding then it has a good reason for it, possibly performance related.
You can also tell the compiler how you detect that two values are the same
bool same_person(struct person* p, struct personDupe* dupe)
{ return p->uid == dupe->uid && p->nameStart == dupe->nameStart; }
And then you can do
if(same_person(&var, &varDupe))
printf("\nStructures are equal\n");

Kind of polymorphism in C

I'm writing a C program in which I define two types:
typedef struct {
uint8_t array[32];
/* struct A's members */
...
} A;
typedef struct {
uint8_t array[32];
/* struct B's members, different from A's */
...
} B;
Now I would like to build a data structure which is capable of managing both types without having to write one for type A and one for type B, assuming that both have a uint8_t [32] as their first member.
I read how to implement a sort of polymorphism in C here and I also read here that the order of struct members is guaranteed to be kept by the compiler as written by the programmer.
I came up with the following idea, what if I define the following structure:
typedef struct {
uint8_t array[32];
} Element;
and define a data structure which only deals with data that have type Element? Would it be safe to do something like:
void f(Element * e){
int i;
for(i = 0; i < 32; i++) do_something(e->array[i]);
}
...
A a;
B b;
...
f(((Element *)&a));
...
f(((Element *)&b));
At a first glance it looks unclean, but I was wondering whether there are any guarantees that it will not break?
If array is always the first in your struct, you can simply access it by casting pointers. There is no need for a struct Element. You data structure can store void pointers.
typedef struct {
char array[32];
} A;
typedef struct {
void* elements;
size_t elementSize;
size_t num;
} Vector;
char* getArrayPtr(Vector* v, int i) {
return (char*)(v->elements) + v->elementSize*i;
}
int main()
{
A* pa = malloc(10*sizeof(A));
pa[3].array[0] = 's';
Vector v;
v.elements = pa;
v.num = 10;
v.elementSize = sizeof(A);
printf("%s\n", getArrayPtr(&v, 3));
}
but why not have a function that works with the array directly
void f(uint8_t array[32]){
int i;
for(i = 0; i < 32; i++) do_something(array[i]);
}
and call it like this
f(a.array)
f(b.array)
polymorphism makes sense when you want to kepp
a and b in a container of some sorts
and you want to iterate over them but you dont want to care that they are different types.
This should work fine if you, you know, don't make any mistakes. A pointer to the A struct can be cast to a pointer to the element struct, and so long as they have a common prefix, access to the common members will work just fine.
A pointer to the A struct, which is then cast to a pointer to the element struct can also be cast back to a pointer to the A struct without any problems. If element struct was not originally an A struct, then casting the pointer back to A will be undefined behavior. And this you will need to manage manually.
One gotcha (that I've run into) is, gcc will also allow you to cast the struct back and forth (not just pointer to struct) and this is not supported by the C standard. It will appear to work fine until your (my) friend tries to port the code to a different compiler (suncc) at which point it will break. Or rather, it won't even compile.

C inheritance through type punning, without containment?

I'm in a position where I need to get some object oriented features working in C, in particular inheritance. Luckily there are some good references on stack overflow, notably this Semi-inheritance in C: How does this snippet work? and this Object-orientation in C. The the idea is to contain an instance of the base class within the derived class and typecast it, like so:
struct base {
int x;
int y;
};
struct derived {
struct base super;
int z;
};
struct derived d;
d.super.x = 1;
d.super.y = 2;
d.z = 3;
struct base b = (struct base *)&d;
This is great, but it becomes cumbersome with deep inheritance trees - I'll have chains of about 5-6 "classes" and I'd really rather not type derived.super.super.super.super.super.super all the time. What I was hoping was that I could typecast to a struct of the first n elements, like this:
struct base {
int x;
int y;
};
struct derived {
int x;
int y;
int z;
};
struct derived d;
d.x = 1;
d.y = 2;
d.z = 3;
struct base b = (struct base *)&d;
I've tested this on the C compiler that comes with Visual Studio 2012 and it works, but I have no idea if the C standard actually guarantees it. Is there anyone that might know for sure if this is ok? I don't want to write mountains of code only to discover it's broken at such a fundamental level.
What you describe here is a construct that was fully portable and would have been essentially guaranteed to work by the design of the language, except that the authors of the Standard didn't think it was necessary to explicitly mandate that compilers support things that should obviously work. C89 specified the Common Initial Sequence rule for unions, rather than pointers to structures, because given:
struct s1 {int x; int y; ... other stuff... };
struct s2 {int x; int y; ... other stuff... };
union u { struct s1 v1; struct s2 v2; };
code which received a struct s1* to an outside object that was either
a union u* or a malloc'ed object could legally cast it to a union u*
if it was aligned for that type, and it could legally cast the resulting
pointer to struct s2*, and the effect of using accessing either struct s1* or struct s2* would have to be the same as accessing the union via either the v1 or v2 member. Consequently, the only way for a compiler to make all of the indicated rules work would be to say that converting a pointer of one structure type into a pointer of another type and using that pointer to inspect members of the Common Initial Sequence would work.
Unfortunately, compiler writers have said that the CIS rule is only applicable in cases where the underlying object has a union type, notwithstanding the fact that such a thing represents a very rare usage case (compared with situations where the union type exists for the purpose of letting the compiler know that pointers to the structures should be treated interchangeably for purposes of inspecting the CIS), and further since it would be rare for code to receive a struct s1* or struct s2* that identifies an object within a union u, they think they should be allowed to ignore that possibility. Thus, even if the above declarations are visible, gcc will assume that a struct s1* will never be used to access members of the CIS from a struct s2*.
By using pointers you can always create references to base classes at any level in the hierarchy. And if you use some kind of description of the inheritance structure, you can generate both the "class definitions" and factory functions needed as a build step.
#include <stdio.h>
#include <stdlib.h>
struct foo_class {
int a;
int b;
};
struct bar_class {
struct foo_class foo;
struct foo_class* base;
int c;
int d;
};
struct gazonk_class {
struct bar_class bar;
struct bar_class* base;
struct foo_class* Foo;
int e;
int f;
};
struct gazonk_class* gazonk_factory() {
struct gazonk_class* new_instance = malloc(sizeof(struct gazonk_class));
new_instance->bar.base = &new_instance->bar.foo;
new_instance->base = &new_instance->bar;
new_instance->Foo = &new_instance->bar.foo;
return new_instance;
}
int main(int argc, char* argv[]) {
struct gazonk_class* object = gazonk_factory();
object->Foo->a = 1;
object->Foo->b = 2;
object->base->c = 3;
object->base->d = 4;
object->e = 5;
object->f = 6;
fprintf(stdout, "%d %d %d %d %d %d\n",
object->base->base->a,
object->base->base->b,
object->base->c,
object->base->d,
object->e,
object->f);
return 0;
}
In this example you can either use base pointers to work your way back or directly reference a base class.
The address of a struct is the address of its first element, guaranteed.

Is there something in C like C++ templates? If not, how to re-use structures and functions for different data types?

I want to write a linked list that can have the data field store any build-in or user-define types. In C++ I would just use a template, but how do I accomplish this in C?
Do I have to re-write the linked list struct and a bunch of operations of it for each data type I want it to store? Unions wouldn't work because what type can it store is predefined.
There's a reason people use languages other than C.... :-)
In C, you'd have your data structure operate with void* members, and you'd cast wherever you used them to the correct types. Macros can help with some of that noise.
There are different approaches to this problem:
using datatype void*: these means, you have pointers to memory locations whose type is not further specified. If you retrieve such a pointer, you can explicitly state what is inside it: *(int*)(mystruct->voidptr) tells the compiler: look at the memory location mystruct->voidptr and interpret the contents as int.
another thing can be tricky preprocessor directives. However, this is usually a very non-trivial issue:
I also found http://sglib.sourceforge.net/
Edit: For the preprocessor trick:
#include <stdio.h>
#define mytype(t) struct { t val; }
int main(int argc, char *argv[]) {
mytype(int) myint;
myint.val=6;
printf ("%d\n", myint.val);
return 0;
}
This would be a simple wrapper for types, but I think it can become quite complicated.
It's less comfortable in C (there's a reason C++ is called C incremented), but it can be done with generic pointers (void *) and the applocation handles the type management itself.
A very nice implementation of generic data structures in C can be found in ubiqx modules, the sources are definitely worth reading.
With some care, you can do this using macros that build and manipulate structs. One of the most well-tested examples of this is the BSD "queue" library. It works on every platform I've tried (Unix, Windows, VMS) and consists of a single header file (no C file).
It has the unfortunate downside of being a bit hard to use, but it preserves as much type-safety as it can in C.
The header file is here: http://www.openbsd.org/cgi-bin/cvsweb/src/sys/sys/queue.h?rev=1.34;content-type=text%2Fplain, and the documentation on how to use it is here: http://www.openbsd.org/cgi-bin/man.cgi?query=queue.
Beyond that, no, you're stuck with losing type-safety (using (void *) all over the place) or moving to the STL.
Here's an option that's very flexible but requires a lot of work.
In your list node, store a pointer to the data as a void *:
struct node {
void *data;
struct node *next;
};
Then you'd create a suite of functions for each type that handle tasks like comparison, assignment, duplication, etc.:
// create a new instance of the data item and copy the value
// of the parameter to it.
void *copyInt(void *src)
{
int *p = malloc(sizeof *p);
if (p) *p = *(int *)src;
return p;
}
void assignInt(void *target, void *src)
{
// we create a new instance for the assignment
*(int *)target = copyInt(src);
}
// returns -1 if lhs < rhs, 0 if lhs == rhs, 1 if lhs > rhs
int testInt(void *lhs, void *rhs)
{
if (*(int *)lhs < *(int *)rhs) return -1;
else if (*(int *)lhs == *(int *)rhs) return 0;
else return 1;
}
char *intToString(void *data)
{
size_t digits = however_many_digits_in_an_int();
char *s = malloc(digits + 2); // sign + digits + terminator
sprintf(s, "%d", *(int *)data);
return s;
}
Then you could create a list type that has pointers to these functions, such as
struct list {
struct node *head;
void *(*cpy)(void *); // copy operation
int (*test)(void *, void *); // test operation
void (*asgn)(void *, void *); // assign operation
char *(*toStr)(void *); // get string representation
...
}
struct list myIntList;
struct list myDoubleList;
myIntList.cpy = copyInt;
myIntList.test = testInt;
myIntList.asgn = assignInt;
myIntList.toStr = intToString;
myDoubleList.cpy = copyDouble;
myDoubleList.test = testDouble;
myDoubleList.asgn = assignDouble;
myDoubleList.toStr = doubleToString;
...
Then, when you pass the list to an insert or search operation, you'd call the functions from the list object:
void addToList(struct list *l, void *value)
{
struct node *new, *cur = l->head;
while (cur->next != NULL && l->test(cur->data, value) <= 0)
cur = cur->next;
new = malloc(sizeof *new);
if (!new)
{
// handle error here
}
else
{
new->data = l->cpy(value);
new->next = cur->next;
cur->next = new;
if (logging)
{
char *s = l->toStr(new->data);
fprintf(log, "Added value %s to list\n", s);
free(s);
}
}
}
...
i = 1;
addToList(&myIntList, &i);
f = 3.4;
addToList(&myDoubleList, &f);
By delegating the type-aware operations to separate functions called through function pointers, you now have a list structure that can store values of any type. To add support for new types, you only need to implement new copy, assign, toString, etc., functions for that new type.
There are drawbacks. For one thing, you can't use constants as function parameters (e.g., you can't do something simple like addToList(&myIntList, 1);) -- you have to assign everything to a variable first, and pass the address of the variable (which is why you need to create new instances of the data member when you add it to the list; if you just assigned the address of the variable, every element in the list would wind up pointing to the same object, which may no longer exist depending on the context).
Secondly, you wind up doing a lot of memory management; you don't just create a new instance of the list node, but you also must create a new instance of the data member. You must remember to free the data member before freeing the node. Then you're creating a new string instance every time you want to display the data, and you have to remember to free that string when you're done with it.
Finally, this solution throws type safety right out the window and into oncoming traffic (after lighting it on fire). The delegate functions are counting on you to keep the types straight; there's nothing preventing you from passing the address of a double variable to one of the int handling functions.
Between the memory management and the fact that you must make a function call for just about every operation, performance is going to suffer. This isn't a fast solution.
Of course, this assumes that every element in the list is the same type; if you're wanting to store elements of different types in the same list, then you're going to have to do something different, such as associate the functions with each node, rather than the list overall.
I wrote a generic linked list "template" in C using the preprocessor, but it's pretty horrible to look at, and heavily pre-processed code is not easy to debug.
These days I think you'd be better off using some other code generation tool such as Python / Cog: http://www.python.org/about/success/cog/
I agree with JonathanPatschke's answer that you should look at sys/queue.h, although I've never tried it myself, as it is not on some of the platforms I work with. I also agree with Vicki's answer to use Python.
But I've found that five or six very simple C macros meet most of my garden-variety needs. These macros help clean up ugly, bug-prone code, without littering it with hidden void *'s, which destroy type-safety. Some of these macros are:
#define ADD_LINK_TO_END_OF_LIST(add, head, tail) \
if (!(head)) \
(tail) = (head) = (add); \
else \
(tail) = (tail)->next = (add)
#define ADD_DOUBLE_LINK_TO_END_OF_LIST(add, head, tail) \
if (!(head)) \
(tail) = (head) = (add); \
else \
(tail) = ((add)->prev = (tail), (tail)->next = (add))
#define FREE_LINK_IN_LIST(p, dtor) do { /* singly-linked */ \
void *myLocalTemporaryPtr = (p)->next; \
dtor(p); \
(p) = myLocalTemporaryPtr;} while (0)
#define FREE_LINKED_LIST(p, dtor) do { \
while (p) \
FREE_LINK_IN_LIST(p, dtor);} while (0)
// copy "ctor" (shallow)
#define NEW_COPY(p) memcpy(myMalloc(sizeof *(p)), p, sizeof *(p))
// iterator
#define NEXT_IN_LIST(p, list) ((p) ? (p)->next : (list))
So, for example:
struct MyContact {
char *name;
char *address;
char *telephone;
...
struct MyContact *next;
} *myContactList = 0, *myContactTail; // the tail doesn't need to be init'd
...
struct MyContact newEntry = {};
...
ADD_LINK_TO_END_OF_LIST(NEW_COPY(newEntry), myContactList, myContactTail);
...
struct MyContact *i = 0;
while ((i = NEXT_IN_LIST(i, myContactList))) // iterate through list
// ...
The next and prev members have hard-coded names. They don't need to be void *, which avoids problems with strict anti-aliasing. They do need to be zeroed when the data item is created.
The dtor argument for FREE_LINK_IN_LIST would typically be a function like free, or (void) to do nothing, or another macro such as:
#define MY_CONTACT_ENTRY_DTOR(p) \
do { if (p) { \
free((p)->name); \
free((p)->address); \
free((p)->telephone); \
free(p); \
}} while (0)
So for example, FREE_LINKED_LIST(myContactList, MY_CONTACT_ENTRY_DTOR) would free all the members of the (duck-typed) list headed by myContactList.
There is one void * here, but perhaps it could be removed via gcc's typeof.
If you need a list that can hold elements of different types simultaneously, e.g. an int followed by three char * followed by a struct tm, then using void * for the data is the solution. But if you only need multiple list types with identical methods, the best solution depends on if you want to avoid generating many instances of almost identical machine code, or just avoid typing source code.
A struct declaration doesn't generate any machine code...
struct int_node {
void *next;
int data;
};
struct long_node {
void *next;
long data;
};
...and one single function which uses a void * parameter and/or return value, can handle them all.
struct generic_node {
void *next;
};
void *insert(void *before_this, void *element, size_t element_sizes);

Resources